diff --git a/contracts/AcrossConfigStore.sol b/contracts/AcrossConfigStore.sol index 6381086ea..92adb3d23 100644 --- a/contracts/AcrossConfigStore.sol +++ b/contracts/AcrossConfigStore.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import "@uma/core/contracts/common/implementation/MultiCaller.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; +import "contracts/external/uma/core/contracts/common/implementation/MultiCaller.sol"; +import "@openzeppelin/contracts-v4/access/Ownable.sol"; /** * @title Allows admin to set and update configuration settings for full contract system. These settings are designed diff --git a/contracts/AdapterStore.sol b/contracts/AdapterStore.sol index 1bf426f4d..bf3605d92 100644 --- a/contracts/AdapterStore.sol +++ b/contracts/AdapterStore.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.18; -import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; +import { Ownable } from "@openzeppelin/contracts-v4/access/Ownable.sol"; import { IOFT } from "./interfaces/IOFT.sol"; /** diff --git a/contracts/Blast_DaiRetriever.sol b/contracts/Blast_DaiRetriever.sol index e472f8a7c..35814d4d3 100644 --- a/contracts/Blast_DaiRetriever.sol +++ b/contracts/Blast_DaiRetriever.sol @@ -3,9 +3,9 @@ pragma solidity ^0.8.0; import "./Lockable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; -import "@uma/core/contracts/common/implementation/MultiCaller.sol"; +import "@openzeppelin/contracts-upgradeable-v4/token/ERC20/IERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable-v4/token/ERC20/utils/SafeERC20Upgradeable.sol"; +import "contracts/external/uma/core/contracts/common/implementation/MultiCaller.sol"; interface USDYieldManager { function claimWithdrawal(uint256 _requestId, uint256 _hintId) external returns (bool success); @@ -36,11 +36,7 @@ contract Blast_DaiRetriever is Lockable, MultiCaller { * @param _usdYieldManager USDCYieldManager contract on Ethereum. * @param _dai DAI token to be retrieved. */ - constructor( - address _hubPool, - USDYieldManager _usdYieldManager, - IERC20Upgradeable _dai - ) { + constructor(address _hubPool, USDYieldManager _usdYieldManager, IERC20Upgradeable _dai) { //slither-disable-next-line missing-zero-check hubPool = _hubPool; usdYieldManager = _usdYieldManager; diff --git a/contracts/BondToken.sol b/contracts/BondToken.sol index bc88873a7..ac2b856e7 100644 --- a/contracts/BondToken.sol +++ b/contracts/BondToken.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; -import "@openzeppelin/contracts/access/Ownable.sol"; -import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts-v4/access/Ownable.sol"; +import "@openzeppelin/contracts-v4/utils/Address.sol"; import "./interfaces/HubPoolInterface.sol"; import "./external/WETH9.sol"; @@ -71,11 +71,7 @@ contract BondToken is WETH9, Ownable { * @param amt Amount to transfer. * @return True on success. */ - function transferFrom( - address src, - address dst, - uint256 amt - ) public override returns (bool) { + function transferFrom(address src, address dst, uint256 amt) public override returns (bool) { if (dst == address(HUB_POOL)) { require(proposers[src] || HUB_POOL.rootBundleProposal().proposer != src, "Transfer not permitted"); } diff --git a/contracts/Ethereum_SpokePool.sol b/contracts/Ethereum_SpokePool.sol index de8660934..a20837bbc 100644 --- a/contracts/Ethereum_SpokePool.sol +++ b/contracts/Ethereum_SpokePool.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import "./SpokePool.sol"; -import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable-v4/access/OwnableUpgradeable.sol"; /** * @notice Ethereum L1 specific SpokePool. Used on Ethereum L1 to facilitate L2->L1 transfers. diff --git a/contracts/HubPool.sol b/contracts/HubPool.sol index ca69b8260..d281fb0a2 100644 --- a/contracts/HubPool.sol +++ b/contracts/HubPool.sol @@ -8,22 +8,22 @@ import "./Lockable.sol"; import "./interfaces/LpTokenFactoryInterface.sol"; import "./external/interfaces/WETH9Interface.sol"; -import "@uma/core/contracts/common/implementation/Testable.sol"; -import "@uma/core/contracts/common/implementation/MultiCaller.sol"; -import "@uma/core/contracts/common/interfaces/AddressWhitelistInterface.sol"; +import "contracts/external/uma/core/contracts/common/implementation/Testable.sol"; +import "contracts/external/uma/core/contracts/common/implementation/MultiCaller.sol"; +import "contracts/external/uma/core/contracts/common/interfaces/AddressWhitelistInterface.sol"; -import "@uma/core/contracts/data-verification-mechanism/interfaces/FinderInterface.sol"; -import "@uma/core/contracts/data-verification-mechanism/interfaces/IdentifierWhitelistInterface.sol"; -import "@uma/core/contracts/data-verification-mechanism/interfaces/StoreInterface.sol"; -import "@uma/core/contracts/data-verification-mechanism/implementation/Constants.sol"; +import "contracts/external/uma/core/contracts/data-verification-mechanism/interfaces/FinderInterface.sol"; +import "contracts/external/uma/core/contracts/data-verification-mechanism/interfaces/IdentifierWhitelistInterface.sol"; +import "contracts/external/uma/core/contracts/data-verification-mechanism/interfaces/StoreInterface.sol"; +import "contracts/external/uma/core/contracts/data-verification-mechanism/implementation/Constants.sol"; -import "@uma/core/contracts/optimistic-oracle-v2/interfaces/SkinnyOptimisticOracleInterface.sol"; -import "@uma/core/contracts/common/interfaces/ExpandedIERC20.sol"; +import "contracts/external/uma/core/contracts/optimistic-oracle-v2/interfaces/SkinnyOptimisticOracleInterface.sol"; +import "contracts/external/uma/core/contracts/common/interfaces/ExpandedIERC20.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts-v4/access/Ownable.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/utils/Address.sol"; /** * @notice Contract deployed on Ethereum that houses L1 token liquidity for all SpokePools. A dataworker can interact @@ -246,12 +246,10 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable { * @param chainId Chain with SpokePool to send message to. * @param functionData ABI encoded function call to send to SpokePool, but can be any arbitrary data technically. */ - function relaySpokePoolAdminFunction(uint256 chainId, bytes memory functionData) - public - override - onlyOwner - nonReentrant - { + function relaySpokePoolAdminFunction( + uint256 chainId, + bytes memory functionData + ) public override onlyOwner nonReentrant { _relaySpokePoolAdminFunction(chainId, functionData); } @@ -260,12 +258,10 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable { * @param newProtocolFeeCaptureAddress New protocol fee capture address. * @param newProtocolFeeCapturePct New protocol fee capture %. */ - function setProtocolFeeCapture(address newProtocolFeeCaptureAddress, uint256 newProtocolFeeCapturePct) - public - override - onlyOwner - nonReentrant - { + function setProtocolFeeCapture( + address newProtocolFeeCaptureAddress, + uint256 newProtocolFeeCapturePct + ) public override onlyOwner nonReentrant { require(newProtocolFeeCapturePct <= 1e18, "Bad protocolFeeCapturePct"); require(newProtocolFeeCaptureAddress != address(0), "Bad protocolFeeCaptureAddress"); protocolFeeCaptureAddress = newProtocolFeeCaptureAddress; @@ -278,13 +274,10 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable { * @param newBondToken New bond currency. * @param newBondAmount New bond amount. */ - function setBond(IERC20 newBondToken, uint256 newBondAmount) - public - override - onlyOwner - noActiveRequests - nonReentrant - { + function setBond( + IERC20 newBondToken, + uint256 newBondAmount + ) public override onlyOwner noActiveRequests nonReentrant { // Bond should not equal final fee otherwise every proposal will get cancelled in a dispute. // In practice we expect that bond amounts are set >> final fees so this shouldn't be an inconvenience. // The only way for the bond amount to be equal to the final fee is if the newBondAmount == 0. @@ -527,11 +520,10 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable { * @param relayedAmount The higher this amount, the higher the utilization. * @return % of liquid reserves currently being "used" and sitting in SpokePools plus the relayedAmount. */ - function liquidityUtilizationPostRelay(address l1Token, uint256 relayedAmount) - public - nonReentrant - returns (uint256) - { + function liquidityUtilizationPostRelay( + address l1Token, + uint256 relayedAmount + ) public nonReentrant returns (uint256) { return _liquidityUtilizationPostRelay(l1Token, relayedAmount); } @@ -826,12 +818,10 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable { * @return destinationToken address The destination token that is sent to spoke pools after this contract bridges * the l1Token to the destination chain. */ - function poolRebalanceRoute(uint256 destinationChainId, address l1Token) - external - view - override - returns (address destinationToken) - { + function poolRebalanceRoute( + uint256 destinationChainId, + address l1Token + ) external view override returns (address destinationToken) { return poolRebalanceRoutes[_poolRebalanceRouteKey(l1Token, destinationChainId)]; } @@ -1043,11 +1033,9 @@ contract HubPool is HubPoolInterface, Testable, Lockable, MultiCaller, Ownable { return keccak256(abi.encode(l1Token, destinationChainId)); } - function _getInitializedCrossChainContracts(uint256 chainId) - internal - view - returns (address adapter, address spokePool) - { + function _getInitializedCrossChainContracts( + uint256 chainId + ) internal view returns (address adapter, address spokePool) { adapter = crossChainContracts[chainId].adapter; spokePool = crossChainContracts[chainId].spokePool; require(spokePool != address(0), "SpokePool not initialized"); diff --git a/contracts/Linea_SpokePool.sol b/contracts/Linea_SpokePool.sol index 926cba52d..22762eb37 100644 --- a/contracts/Linea_SpokePool.sol +++ b/contracts/Linea_SpokePool.sol @@ -7,8 +7,8 @@ pragma solidity ^0.8.19; import "./SpokePool.sol"; import "./libraries/CircleCCTPAdapter.sol"; import { IMessageService, ITokenBridge, IUSDCBridge } from "./external/interfaces/LineaInterfaces.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; /** * @notice Linea specific SpokePool. diff --git a/contracts/LpTokenFactory.sol b/contracts/LpTokenFactory.sol index b7e2e40c9..eafb7ce01 100644 --- a/contracts/LpTokenFactory.sol +++ b/contracts/LpTokenFactory.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import "./interfaces/LpTokenFactoryInterface.sol"; -import "@uma/core/contracts/common/implementation/ExpandedERC20.sol"; +import "contracts/external/uma/core/contracts/common/implementation/ExpandedERC20.sol"; /** * @notice Factory to create new LP ERC20 tokens that represent a liquidity provider's position. HubPool is the @@ -30,11 +30,7 @@ contract LpTokenFactory is LpTokenFactoryInterface { return address(lpToken); } - function _concatenate( - string memory a, - string memory b, - string memory c - ) internal pure returns (string memory) { + function _concatenate(string memory a, string memory b, string memory c) internal pure returns (string memory) { return string(abi.encodePacked(a, b, c)); } } diff --git a/contracts/MerkleLib.sol b/contracts/MerkleLib.sol index a606b29d0..688bfaf2b 100644 --- a/contracts/MerkleLib.sol +++ b/contracts/MerkleLib.sol @@ -5,7 +5,7 @@ import "./interfaces/SpokePoolInterface.sol"; import "./interfaces/V3SpokePoolInterface.sol"; import "./interfaces/HubPoolInterface.sol"; -import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; +import "@openzeppelin/contracts-v4/utils/cryptography/MerkleProof.sol"; /** * @notice Library to help with merkle roots, proofs, and claims. diff --git a/contracts/Ovm_SpokePool.sol b/contracts/Ovm_SpokePool.sol index 22c9e1e4d..97085ebca 100644 --- a/contracts/Ovm_SpokePool.sol +++ b/contracts/Ovm_SpokePool.sol @@ -5,7 +5,7 @@ import "./SpokePool.sol"; import "./external/interfaces/WETH9Interface.sol"; import "./libraries/CircleCCTPAdapter.sol"; -import "@openzeppelin/contracts-upgradeable/crosschain/optimism/LibOptimismUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable-v4/crosschain/optimism/LibOptimismUpgradeable.sol"; import "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol"; // https://github.com/ethereum-optimism/optimism/blob/bf51c4935261634120f31827c3910aa631f6bf9c/packages/contracts-bedrock/contracts/L2/L2StandardBridge.sol diff --git a/contracts/PermissionSplitterProxy.sol b/contracts/PermissionSplitterProxy.sol index eebbd07e0..76df44f6c 100644 --- a/contracts/PermissionSplitterProxy.sol +++ b/contracts/PermissionSplitterProxy.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.0; -import "@uma/core/contracts/common/implementation/MultiCaller.sol"; -import "@openzeppelin/contracts/access/AccessControl.sol"; +import "contracts/external/uma/core/contracts/common/implementation/MultiCaller.sol"; +import "@openzeppelin/contracts-v4/access/AccessControl.sol"; /** * @notice This contract is designed to own an Ownable "target" contract and gate access to specific diff --git a/contracts/PolygonTokenBridger.sol b/contracts/PolygonTokenBridger.sol index ab5dac349..4a623f62e 100644 --- a/contracts/PolygonTokenBridger.sol +++ b/contracts/PolygonTokenBridger.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.0; import "./Lockable.sol"; import "./external/interfaces/WETH9Interface.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable-v4/token/ERC20/IERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable-v4/token/ERC20/utils/SafeERC20Upgradeable.sol"; // Polygon Registry contract that stores their addresses. interface PolygonRegistry { diff --git a/contracts/PolygonZkEVM_SpokePool.sol b/contracts/PolygonZkEVM_SpokePool.sol index 0165a3913..25958643f 100644 --- a/contracts/PolygonZkEVM_SpokePool.sol +++ b/contracts/PolygonZkEVM_SpokePool.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.0; import "./SpokePool.sol"; import "./external/interfaces/IPolygonZkEVMBridge.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; /** * @notice Define interface for PolygonZkEVM Bridge message receiver @@ -18,11 +18,7 @@ interface IBridgeMessageReceiver { * @param originNetwork Polygon zkEVM's internal network id of source chain. * @param data Data to be received and executed on this contract. */ - function onMessageReceived( - address originAddress, - uint32 originNetwork, - bytes memory data - ) external payable; + function onMessageReceived(address originAddress, uint32 originNetwork, bytes memory data) external payable; } /** diff --git a/contracts/SpokePool.sol b/contracts/SpokePool.sol index b9656ddb2..4aa181a96 100644 --- a/contracts/SpokePool.sol +++ b/contracts/SpokePool.sol @@ -15,12 +15,12 @@ import "./libraries/AddressConverters.sol"; import { IOFT, SendParam, MessagingFee } from "./interfaces/IOFT.sol"; import { OFTTransportAdapter } from "./libraries/OFTTransportAdapter.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; -import "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; -import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; -import "@openzeppelin/contracts/utils/math/SignedMath.sol"; +import "@openzeppelin/contracts-upgradeable-v4/token/ERC20/IERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable-v4/token/ERC20/utils/SafeERC20Upgradeable.sol"; +import "@openzeppelin/contracts-v4/utils/cryptography/SignatureChecker.sol"; +import "@openzeppelin/contracts-upgradeable-v4/proxy/utils/UUPSUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable-v4/security/ReentrancyGuardUpgradeable.sol"; +import "@openzeppelin/contracts-v4/utils/math/SignedMath.sol"; /** * @title SpokePool diff --git a/contracts/SpokePoolPeriphery.sol b/contracts/SpokePoolPeriphery.sol index 4733ac9c6..effdfe712 100644 --- a/contracts/SpokePoolPeriphery.sol +++ b/contracts/SpokePoolPeriphery.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.0; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { IERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol"; -import { Address } from "@openzeppelin/contracts/utils/Address.sol"; -import { MultiCaller } from "@uma/core/contracts/common/implementation/MultiCaller.sol"; -import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import { SignatureChecker } from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; -import { EIP712 } from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import { SafeERC20 } from "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; +import { IERC20Permit } from "@openzeppelin/contracts-v4/token/ERC20/extensions/IERC20Permit.sol"; +import { Address } from "@openzeppelin/contracts-v4/utils/Address.sol"; +import { MultiCaller } from "contracts/external/uma/core/contracts/common/implementation/MultiCaller.sol"; +import { ReentrancyGuard } from "@openzeppelin/contracts-v4/security/ReentrancyGuard.sol"; +import { SignatureChecker } from "@openzeppelin/contracts-v4/utils/cryptography/SignatureChecker.sol"; +import { EIP712 } from "@openzeppelin/contracts-v4/utils/cryptography/EIP712.sol"; import { V3SpokePoolInterface } from "./interfaces/V3SpokePoolInterface.sol"; import { IERC20Auth } from "./external/interfaces/IERC20Auth.sol"; import { WETH9Interface } from "./external/interfaces/WETH9Interface.sol"; diff --git a/contracts/SpokePoolVerifier.sol b/contracts/SpokePoolVerifier.sol index a4f2774c9..c07946486 100644 --- a/contracts/SpokePoolVerifier.sol +++ b/contracts/SpokePoolVerifier.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts-v4/utils/Address.sol"; import "./interfaces/V3SpokePoolInterface.sol"; import { AddressToBytes32 } from "./libraries/AddressConverters.sol"; diff --git a/contracts/Universal_SpokePool.sol b/contracts/Universal_SpokePool.sol index 4bf8b34ed..d9c87174a 100644 --- a/contracts/Universal_SpokePool.sol +++ b/contracts/Universal_SpokePool.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable-v4/access/OwnableUpgradeable.sol"; import { IHelios } from "./external/interfaces/IHelios.sol"; import "./libraries/CircleCCTPAdapter.sol"; diff --git a/contracts/ZkSync_SpokePool.sol b/contracts/ZkSync_SpokePool.sol index 83c51a633..2138cd9d7 100644 --- a/contracts/ZkSync_SpokePool.sol +++ b/contracts/ZkSync_SpokePool.sol @@ -1,18 +1,14 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import { CircleCCTPAdapter, CircleDomainIds, ITokenMessenger } from "./libraries/CircleCCTPAdapter.sol"; import { CrossDomainAddressUtils } from "./libraries/CrossDomainAddressUtils.sol"; import "./SpokePool.sol"; // https://github.com/matter-labs/era-contracts/blob/6391c0d7bf6184d7f6718060e3991ba6f0efe4a7/zksync/contracts/bridge/L2ERC20Bridge.sol#L104 interface ZkBridgeLike { - function withdraw( - address _l1Receiver, - address _l2Token, - uint256 _amount - ) external; + function withdraw(address _l1Receiver, address _l2Token, uint256 _amount) external; } interface IL2ETH { diff --git a/contracts/chain-adapters/Arbitrum_Adapter.sol b/contracts/chain-adapters/Arbitrum_Adapter.sol index 1f215c8d0..493b0e8b0 100644 --- a/contracts/chain-adapters/Arbitrum_Adapter.sol +++ b/contracts/chain-adapters/Arbitrum_Adapter.sol @@ -3,8 +3,8 @@ pragma solidity ^0.8.0; import "./interfaces/AdapterInterface.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import { IOFT } from "../interfaces/IOFT.sol"; import "../external/interfaces/CCTPInterfaces.sol"; import "../libraries/CircleCCTPAdapter.sol"; diff --git a/contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol b/contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol index 1093145ac..8e7369cb0 100644 --- a/contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol +++ b/contracts/chain-adapters/Arbitrum_CustomGasToken_Adapter.sol @@ -3,8 +3,8 @@ pragma solidity ^0.8.0; import { AdapterInterface } from "./interfaces/AdapterInterface.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import { SafeERC20 } from "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import { ITokenMessenger as ICCTPTokenMessenger } from "../external/interfaces/CCTPInterfaces.sol"; import { CircleCCTPAdapter, CircleDomainIds } from "../libraries/CircleCCTPAdapter.sol"; import { ArbitrumERC20Bridge as ArbitrumL1ERC20Bridge, ArbitrumCustomGasTokenInbox as ArbitrumL1InboxLike, ArbitrumL1ERC20GatewayLike } from "../interfaces/ArbitrumBridge.sol"; @@ -243,7 +243,7 @@ contract Arbitrum_CustomGasToken_Adapter is AdapterInterface, CircleCCTPAdapter return amount; } else if (NATIVE_TOKEN_DECIMALS < 18) { // Round up the division result so that the L1 call value is always sufficient to cover the submission fee. - uint256 reductionFactor = 10**(18 - NATIVE_TOKEN_DECIMALS); + uint256 reductionFactor = 10 ** (18 - NATIVE_TOKEN_DECIMALS); uint256 divFloor = amount / reductionFactor; uint256 mod = amount % reductionFactor; if (mod != 0) { @@ -252,7 +252,7 @@ contract Arbitrum_CustomGasToken_Adapter is AdapterInterface, CircleCCTPAdapter return divFloor; } } else { - return amount * 10**(NATIVE_TOKEN_DECIMALS - 18); + return amount * 10 ** (NATIVE_TOKEN_DECIMALS - 18); } } @@ -260,9 +260,9 @@ contract Arbitrum_CustomGasToken_Adapter is AdapterInterface, CircleCCTPAdapter if (NATIVE_TOKEN_DECIMALS == 18) { return amount; } else if (NATIVE_TOKEN_DECIMALS < 18) { - return amount * 10**(18 - NATIVE_TOKEN_DECIMALS); + return amount * 10 ** (18 - NATIVE_TOKEN_DECIMALS); } else { - return amount / 10**(NATIVE_TOKEN_DECIMALS - 18); + return amount / 10 ** (NATIVE_TOKEN_DECIMALS - 18); } } } diff --git a/contracts/chain-adapters/Arbitrum_RescueAdapter.sol b/contracts/chain-adapters/Arbitrum_RescueAdapter.sol index 1a66e5133..80aeb0009 100644 --- a/contracts/chain-adapters/Arbitrum_RescueAdapter.sol +++ b/contracts/chain-adapters/Arbitrum_RescueAdapter.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.0; import "./interfaces/AdapterInterface.sol"; import "./Arbitrum_Adapter.sol"; // Used to import `ArbitrumL1ERC20GatewayLike` and `ArbitrumL1InboxLike` -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; /** * @notice Meant to copy the Arbitrum_Adapter exactly in how it sends L1 --> L2 messages but is designed only to be @@ -84,12 +84,7 @@ contract Arbitrum_RescueAdapter is AdapterInterface { /** * @notice Should never be called. */ - function relayTokens( - address, - address, - uint256, - address - ) external payable override { + function relayTokens(address, address, uint256, address) external payable override { revert("useless function"); } diff --git a/contracts/chain-adapters/Arbitrum_SendTokensAdapter.sol b/contracts/chain-adapters/Arbitrum_SendTokensAdapter.sol index 344684363..6ec9614e7 100644 --- a/contracts/chain-adapters/Arbitrum_SendTokensAdapter.sol +++ b/contracts/chain-adapters/Arbitrum_SendTokensAdapter.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.0; import "./interfaces/AdapterInterface.sol"; import { ArbitrumL1ERC20GatewayLike } from "./Arbitrum_Adapter.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; /** * @notice This adapter is built for emergencies to send funds from the Hub to a Spoke in the event that a spoke pool @@ -70,12 +70,7 @@ contract Arbitrum_SendTokensAdapter is AdapterInterface { /** * @notice Should never be called. */ - function relayTokens( - address, - address, - uint256, - address - ) external payable override { + function relayTokens(address, address, uint256, address) external payable override { revert("relayTokens disabled"); } diff --git a/contracts/chain-adapters/Base_Adapter.sol b/contracts/chain-adapters/Base_Adapter.sol index f79f1b7e1..9b9b2bc05 100644 --- a/contracts/chain-adapters/Base_Adapter.sol +++ b/contracts/chain-adapters/Base_Adapter.sol @@ -9,8 +9,8 @@ import "../external/interfaces/WETH9Interface.sol"; import "./CrossDomainEnabled.sol"; import "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import "../libraries/CircleCCTPAdapter.sol"; import "../external/interfaces/CCTPInterfaces.sol"; @@ -70,12 +70,7 @@ contract Base_Adapter is CrossDomainEnabled, AdapterInterface, CircleCCTPAdapter * @param amount Amount of L1 tokens to deposit and L2 tokens to receive. * @param to Bridge recipient. */ - function relayTokens( - address l1Token, - address l2Token, - uint256 amount, - address to - ) external payable override { + function relayTokens(address l1Token, address l2Token, uint256 amount, address to) external payable override { // If the l1Token is weth then unwrap it to ETH then send the ETH to the standard bridge. if (l1Token == address(L1_WETH)) { L1_WETH.withdraw(amount); diff --git a/contracts/chain-adapters/Blast_Adapter.sol b/contracts/chain-adapters/Blast_Adapter.sol index e3cdc514d..a5a8cf410 100644 --- a/contracts/chain-adapters/Blast_Adapter.sol +++ b/contracts/chain-adapters/Blast_Adapter.sol @@ -9,8 +9,8 @@ import "../external/interfaces/WETH9Interface.sol"; import "./CrossDomainEnabled.sol"; import { IL1StandardBridge } from "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import "../libraries/CircleCCTPAdapter.sol"; import "../external/interfaces/CCTPInterfaces.sol"; @@ -102,12 +102,7 @@ contract Blast_Adapter is CrossDomainEnabled, AdapterInterface, CircleCCTPAdapte * @param amount Amount of L1 tokens to deposit and L2 tokens to receive. * @param to Bridge recipient. */ - function relayTokens( - address l1Token, - address l2Token, - uint256 amount, - address to - ) external payable override { + function relayTokens(address l1Token, address l2Token, uint256 amount, address to) external payable override { // If token can be bridged into yield-ing version of ERC20 on L2 side, then use Blast Bridge, otherwise // use standard bridge. diff --git a/contracts/chain-adapters/Blast_RescueAdapter.sol b/contracts/chain-adapters/Blast_RescueAdapter.sol index 5b4140983..bf501f99d 100644 --- a/contracts/chain-adapters/Blast_RescueAdapter.sol +++ b/contracts/chain-adapters/Blast_RescueAdapter.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.0; import "./interfaces/AdapterInterface.sol"; import { USDYieldManager } from "../Blast_DaiRetriever.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; /** * @notice This adapter is built to to retrieve Blast USDB from the USDBYieldManager contract on Ethereum that was @@ -41,12 +41,7 @@ contract Blast_RescueAdapter is AdapterInterface { /** * @notice Should never be called. */ - function relayTokens( - address, - address, - uint256, - address - ) external payable override { + function relayTokens(address, address, uint256, address) external payable override { revert("relayTokens disabled"); } } diff --git a/contracts/chain-adapters/Boba_Adapter.sol b/contracts/chain-adapters/Boba_Adapter.sol index 76e23af07..bc859dcd9 100644 --- a/contracts/chain-adapters/Boba_Adapter.sol +++ b/contracts/chain-adapters/Boba_Adapter.sol @@ -9,8 +9,8 @@ import "../external/interfaces/WETH9Interface.sol"; import "./CrossDomainEnabled.sol"; import "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; /** * @notice Contract containing logic to send messages from L1 to Boba. This is a modified version of the Optimism adapter @@ -62,12 +62,7 @@ contract Boba_Adapter is CrossDomainEnabled, AdapterInterface { * @param amount Amount of L1 tokens to deposit and L2 tokens to receive. * @param to Bridge recipient. */ - function relayTokens( - address l1Token, - address l2Token, - uint256 amount, - address to - ) external payable override { + function relayTokens(address l1Token, address l2Token, uint256 amount, address to) external payable override { // If the l1Token is weth then unwrap it to ETH then send the ETH to the standard bridge. if (l1Token == address(L1_WETH)) { L1_WETH.withdraw(amount); diff --git a/contracts/chain-adapters/DoctorWho_Adapter.sol b/contracts/chain-adapters/DoctorWho_Adapter.sol index 75af3aa41..2275892f0 100644 --- a/contracts/chain-adapters/DoctorWho_Adapter.sol +++ b/contracts/chain-adapters/DoctorWho_Adapter.sol @@ -9,8 +9,8 @@ import "../external/interfaces/WETH9Interface.sol"; import "./CrossDomainEnabled.sol"; import "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import "../libraries/CircleCCTPAdapter.sol"; import "../external/interfaces/CCTPInterfaces.sol"; @@ -73,12 +73,7 @@ contract DoctorWho_Adapter is CrossDomainEnabled, AdapterInterface, CircleCCTPAd * @param amount Amount of L1 tokens to deposit and L2 tokens to receive. * @param to Bridge recipient. */ - function relayTokens( - address l1Token, - address l2Token, - uint256 amount, - address to - ) external payable override { + function relayTokens(address l1Token, address l2Token, uint256 amount, address to) external payable override { // If the l1Token is weth then unwrap it to ETH then send the ETH to the standard bridge. if (l1Token == address(L1_WETH)) { L1_WETH.withdraw(amount); diff --git a/contracts/chain-adapters/DonationBox.sol b/contracts/chain-adapters/DonationBox.sol index 6c1221848..9a0eff508 100644 --- a/contracts/chain-adapters/DonationBox.sol +++ b/contracts/chain-adapters/DonationBox.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import { Ownable } from "@openzeppelin/contracts-v4/access/Ownable.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import { SafeERC20 } from "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; /** * @notice Users can donate tokens to this contract that only the owner can withdraw. diff --git a/contracts/chain-adapters/Ethereum_Adapter.sol b/contracts/chain-adapters/Ethereum_Adapter.sol index ceef12ab3..b6c5ea07a 100644 --- a/contracts/chain-adapters/Ethereum_Adapter.sol +++ b/contracts/chain-adapters/Ethereum_Adapter.sol @@ -3,8 +3,8 @@ pragma solidity ^0.8.0; import "./interfaces/AdapterInterface.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; /** * @custom:security-contact bugs@across.to diff --git a/contracts/chain-adapters/Ethereum_RescueAdapter.sol b/contracts/chain-adapters/Ethereum_RescueAdapter.sol index c8fc200ac..cebb14462 100644 --- a/contracts/chain-adapters/Ethereum_RescueAdapter.sol +++ b/contracts/chain-adapters/Ethereum_RescueAdapter.sol @@ -3,8 +3,8 @@ pragma solidity ^0.8.0; import "./interfaces/AdapterInterface.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; /** * @notice This adapter is built for emergencies to rescue funds from a Hub in the event of a misconfiguration or @@ -38,12 +38,7 @@ contract Ethereum_RescueAdapter is AdapterInterface { /** * @notice Should never be called. */ - function relayTokens( - address, - address, - uint256, - address - ) external payable override { + function relayTokens(address, address, uint256, address) external payable override { revert("relayTokens disabled"); } } diff --git a/contracts/chain-adapters/ForwarderBase.sol b/contracts/chain-adapters/ForwarderBase.sol index 0e793cded..a4ddc1b9e 100644 --- a/contracts/chain-adapters/ForwarderBase.sol +++ b/contracts/chain-adapters/ForwarderBase.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; +import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable-v4/proxy/utils/UUPSUpgradeable.sol"; +import { ReentrancyGuardUpgradeable } from "@openzeppelin/contracts-upgradeable-v4/security/ReentrancyGuardUpgradeable.sol"; import { ForwarderInterface } from "./interfaces/ForwarderInterface.sol"; import { AdapterInterface } from "./interfaces/AdapterInterface.sol"; -import { MultiCaller } from "@uma/core/contracts/common/implementation/MultiCaller.sol"; +import { MultiCaller } from "../external/uma/core/contracts/common/implementation/MultiCaller.sol"; import { WETH9Interface } from "../external/interfaces/WETH9Interface.sol"; /** diff --git a/contracts/chain-adapters/Linea_Adapter.sol b/contracts/chain-adapters/Linea_Adapter.sol index 1af43e06c..97e3afb41 100644 --- a/contracts/chain-adapters/Linea_Adapter.sol +++ b/contracts/chain-adapters/Linea_Adapter.sol @@ -7,8 +7,8 @@ import "../libraries/CircleCCTPAdapter.sol"; import { IMessageService, ITokenBridge, IUSDCBridge } from "../external/interfaces/LineaInterfaces.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; /** * @notice Supports sending messages and tokens from L1 to Linea. @@ -60,12 +60,7 @@ contract Linea_Adapter is AdapterInterface, CircleCCTPAdapter { * @param amount Amount of L1 tokens to deposit and L2 tokens to receive. * @param to Bridge recipient. */ - function relayTokens( - address l1Token, - address l2Token, - uint256 amount, - address to - ) external payable override { + function relayTokens(address l1Token, address l2Token, uint256 amount, address to) external payable override { if (l1Token == address(usdcToken) && _isCCTPEnabled()) { _transferUsdc(to, amount); } diff --git a/contracts/chain-adapters/Lisk_Adapter.sol b/contracts/chain-adapters/Lisk_Adapter.sol index bea4f65f0..ea240f6ef 100644 --- a/contracts/chain-adapters/Lisk_Adapter.sol +++ b/contracts/chain-adapters/Lisk_Adapter.sol @@ -9,8 +9,8 @@ import "../external/interfaces/WETH9Interface.sol"; import "./CrossDomainEnabled.sol"; import "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import "../libraries/CircleCCTPAdapter.sol"; import "../external/interfaces/CCTPInterfaces.sol"; @@ -75,12 +75,7 @@ contract Lisk_Adapter is CrossDomainEnabled, AdapterInterface, CircleCCTPAdapter * @param amount Amount of L1 tokens to deposit and L2 tokens to receive. * @param to Bridge recipient. */ - function relayTokens( - address l1Token, - address l2Token, - uint256 amount, - address to - ) external payable override { + function relayTokens(address l1Token, address l2Token, uint256 amount, address to) external payable override { // If the l1Token is weth then unwrap it to ETH then send the ETH to the standard bridge. if (l1Token == address(L1_WETH)) { L1_WETH.withdraw(amount); diff --git a/contracts/chain-adapters/Mock_Adapter.sol b/contracts/chain-adapters/Mock_Adapter.sol index 3095ab138..88caa7ba6 100644 --- a/contracts/chain-adapters/Mock_Adapter.sol +++ b/contracts/chain-adapters/Mock_Adapter.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import "./interfaces/AdapterInterface.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; /** * @notice Contract used for testing communication between HubPool and Adapter. @@ -25,12 +25,7 @@ contract Mock_Adapter is AdapterInterface { emit RelayMessageCalled(target, message, msg.sender); } - function relayTokens( - address l1Token, - address l2Token, - uint256 amount, - address to - ) external payable override { + function relayTokens(address l1Token, address l2Token, uint256 amount, address to) external payable override { IERC20(l1Token).approve(address(bridge), amount); bridge.bridgeTokens(l1Token, amount); emit RelayTokensCalled(l1Token, l2Token, amount, to, msg.sender); diff --git a/contracts/chain-adapters/Mode_Adapter.sol b/contracts/chain-adapters/Mode_Adapter.sol index 29e398779..0467183e1 100644 --- a/contracts/chain-adapters/Mode_Adapter.sol +++ b/contracts/chain-adapters/Mode_Adapter.sol @@ -9,8 +9,8 @@ import "../external/interfaces/WETH9Interface.sol"; import "./CrossDomainEnabled.sol"; import "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import "../libraries/CircleCCTPAdapter.sol"; import "../external/interfaces/CCTPInterfaces.sol"; @@ -75,12 +75,7 @@ contract Mode_Adapter is CrossDomainEnabled, AdapterInterface, CircleCCTPAdapter * @param amount Amount of L1 tokens to deposit and L2 tokens to receive. * @param to Bridge recipient. */ - function relayTokens( - address l1Token, - address l2Token, - uint256 amount, - address to - ) external payable override { + function relayTokens(address l1Token, address l2Token, uint256 amount, address to) external payable override { // If the l1Token is weth then unwrap it to ETH then send the ETH to the standard bridge. if (l1Token == address(L1_WETH)) { L1_WETH.withdraw(amount); diff --git a/contracts/chain-adapters/OP_Adapter.sol b/contracts/chain-adapters/OP_Adapter.sol index d33817649..0fcf1a975 100644 --- a/contracts/chain-adapters/OP_Adapter.sol +++ b/contracts/chain-adapters/OP_Adapter.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.0; import "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import { CircleCCTPAdapter, CircleDomainIds } from "../libraries/CircleCCTPAdapter.sol"; import { ITokenMessenger } from "../external/interfaces/CCTPInterfaces.sol"; @@ -79,12 +79,7 @@ contract OP_Adapter is CrossDomainEnabled, AdapterInterface, CircleCCTPAdapter { * @param amount Amount of L1 tokens to deposit and L2 tokens to receive. * @param to Bridge recipient. */ - function relayTokens( - address l1Token, - address l2Token, - uint256 amount, - address to - ) external payable override { + function relayTokens(address l1Token, address l2Token, uint256 amount, address to) external payable override { // If the l1Token is weth then unwrap it to ETH then send the ETH to the standard bridge. if (l1Token == address(L1_WETH)) { L1_WETH.withdraw(amount); diff --git a/contracts/chain-adapters/Optimism_Adapter.sol b/contracts/chain-adapters/Optimism_Adapter.sol index 22eadabec..ab0a09f79 100644 --- a/contracts/chain-adapters/Optimism_Adapter.sol +++ b/contracts/chain-adapters/Optimism_Adapter.sol @@ -11,8 +11,8 @@ import "../external/interfaces/CCTPInterfaces.sol"; import "./CrossDomainEnabled.sol"; import "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; /** * @notice Interface for Synthetix custom bridge to Optimism. @@ -93,12 +93,7 @@ contract Optimism_Adapter is CrossDomainEnabled, AdapterInterface, CircleCCTPAda * @param amount Amount of L1 tokens to deposit and L2 tokens to receive. * @param to Bridge recipient. */ - function relayTokens( - address l1Token, - address l2Token, - uint256 amount, - address to - ) external payable override { + function relayTokens(address l1Token, address l2Token, uint256 amount, address to) external payable override { // If the l1Token is weth then unwrap it to ETH then send the ETH to the standard bridge. if (l1Token == address(L1_WETH)) { L1_WETH.withdraw(amount); diff --git a/contracts/chain-adapters/Ovm_Forwarder.sol b/contracts/chain-adapters/Ovm_Forwarder.sol index 116dcba4d..c950dff7d 100644 --- a/contracts/chain-adapters/Ovm_Forwarder.sol +++ b/contracts/chain-adapters/Ovm_Forwarder.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import { ForwarderBase } from "./ForwarderBase.sol"; -import { LibOptimismUpgradeable } from "@openzeppelin/contracts-upgradeable/crosschain/optimism/LibOptimismUpgradeable.sol"; +import { LibOptimismUpgradeable } from "@openzeppelin/contracts-upgradeable-v4/crosschain/optimism/LibOptimismUpgradeable.sol"; import { Lib_PredeployAddresses } from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol"; import { WETH9Interface } from "../external/interfaces/WETH9Interface.sol"; diff --git a/contracts/chain-adapters/PolygonZkEVM_Adapter.sol b/contracts/chain-adapters/PolygonZkEVM_Adapter.sol index 318e87195..08b8a9cf0 100644 --- a/contracts/chain-adapters/PolygonZkEVM_Adapter.sol +++ b/contracts/chain-adapters/PolygonZkEVM_Adapter.sol @@ -5,8 +5,8 @@ import "./interfaces/AdapterInterface.sol"; import "../external/interfaces/WETH9Interface.sol"; import "../external/interfaces/IPolygonZkEVMBridge.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; /** * @notice Supports sending messages and tokens from L1 to PolygonZkEVM. @@ -51,12 +51,7 @@ contract PolygonZkEVM_Adapter is AdapterInterface { * @param amount Amount of L1 tokens to deposit and L2 tokens to receive. * @param to Bridge recipient. */ - function relayTokens( - address l1Token, - address l2Token, - uint256 amount, - address to - ) external payable override { + function relayTokens(address l1Token, address l2Token, uint256 amount, address to) external payable override { // The mapped WETH address in the native Polygon zkEVM bridge contract does not match // the official WETH address. Therefore, if the l1Token is WETH then unwrap it to ETH // and send the ETH directly via as msg.value. diff --git a/contracts/chain-adapters/Polygon_Adapter.sol b/contracts/chain-adapters/Polygon_Adapter.sol index 37698a16f..08ea8005e 100644 --- a/contracts/chain-adapters/Polygon_Adapter.sol +++ b/contracts/chain-adapters/Polygon_Adapter.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.0; import "./interfaces/AdapterInterface.sol"; import "../external/interfaces/WETH9Interface.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import "../libraries/CircleCCTPAdapter.sol"; import "../external/interfaces/CCTPInterfaces.sol"; diff --git a/contracts/chain-adapters/Redstone_Adapter.sol b/contracts/chain-adapters/Redstone_Adapter.sol index 65fc07a42..8cb5926c8 100644 --- a/contracts/chain-adapters/Redstone_Adapter.sol +++ b/contracts/chain-adapters/Redstone_Adapter.sol @@ -9,8 +9,8 @@ import "../external/interfaces/WETH9Interface.sol"; import "./CrossDomainEnabled.sol"; import "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import "../libraries/CircleCCTPAdapter.sol"; import "../external/interfaces/CCTPInterfaces.sol"; @@ -75,12 +75,7 @@ contract Redstone_Adapter is CrossDomainEnabled, AdapterInterface, CircleCCTPAda * @param amount Amount of L1 tokens to deposit and L2 tokens to receive. * @param to Bridge recipient. */ - function relayTokens( - address l1Token, - address l2Token, - uint256 amount, - address to - ) external payable override { + function relayTokens(address l1Token, address l2Token, uint256 amount, address to) external payable override { // If the l1Token is weth then unwrap it to ETH then send the ETH to the standard bridge. if (l1Token == address(L1_WETH)) { L1_WETH.withdraw(amount); diff --git a/contracts/chain-adapters/Scroll_Adapter.sol b/contracts/chain-adapters/Scroll_Adapter.sol index aa7ec7509..5c7dc1eeb 100644 --- a/contracts/chain-adapters/Scroll_Adapter.sol +++ b/contracts/chain-adapters/Scroll_Adapter.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import "@scroll-tech/contracts/L1/gateways/IL1GatewayRouter.sol"; import "@scroll-tech/contracts/L1/rollup/IL2GasPriceOracle.sol"; import "@scroll-tech/contracts/L1/IL1ScrollMessenger.sol"; @@ -103,12 +103,7 @@ contract Scroll_Adapter is AdapterInterface { * @param amount Amount of `l1Token` to bridge. * @param to Bridge recipient. */ - function relayTokens( - address l1Token, - address l2Token, - uint256 amount, - address to - ) external payable { + function relayTokens(address l1Token, address l2Token, uint256 amount, address to) external payable { IL1GatewayRouter _l1GatewayRouter = L1_GATEWAY_ROUTER; // Confirm that the l2Token that we're trying to send is the correct counterpart diff --git a/contracts/chain-adapters/Solana_Adapter.sol b/contracts/chain-adapters/Solana_Adapter.sol index f85cd1e46..f3c1742c5 100644 --- a/contracts/chain-adapters/Solana_Adapter.sol +++ b/contracts/chain-adapters/Solana_Adapter.sol @@ -7,7 +7,7 @@ import { AdapterInterface } from "./interfaces/AdapterInterface.sol"; import { CircleCCTPAdapter, CircleDomainIds } from "../libraries/CircleCCTPAdapter.sol"; import { Bytes32ToAddress } from "../libraries/AddressConverters.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; /** * @notice Contract containing logic to send messages from L1 to Solana via CCTP. @@ -119,12 +119,7 @@ contract Solana_Adapter is AdapterInterface, CircleCCTPAdapter { * @param amount Amount of L1 tokens to deposit and L2 tokens to receive. * @param to Bridge recipient. */ - function relayTokens( - address l1Token, - address l2Token, - uint256 amount, - address to - ) external payable override { + function relayTokens(address l1Token, address l2Token, uint256 amount, address to) external payable override { if (l1Token != address(usdcToken)) { revert InvalidL1Token(l1Token); } diff --git a/contracts/chain-adapters/ZkStack_Adapter.sol b/contracts/chain-adapters/ZkStack_Adapter.sol index 81b379da1..166dda74f 100644 --- a/contracts/chain-adapters/ZkStack_Adapter.sol +++ b/contracts/chain-adapters/ZkStack_Adapter.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.0; import "./interfaces/AdapterInterface.sol"; import "../external/interfaces/WETH9Interface.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import { BridgeHubInterface } from "../interfaces/ZkStackBridgeHub.sol"; import { CircleCCTPAdapter } from "../libraries/CircleCCTPAdapter.sol"; import { ITokenMessenger } from "../external/interfaces/CCTPInterfaces.sol"; diff --git a/contracts/chain-adapters/ZkStack_CustomGasToken_Adapter.sol b/contracts/chain-adapters/ZkStack_CustomGasToken_Adapter.sol index cf638b223..b0562c8bb 100644 --- a/contracts/chain-adapters/ZkStack_CustomGasToken_Adapter.sol +++ b/contracts/chain-adapters/ZkStack_CustomGasToken_Adapter.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.0; import "./interfaces/AdapterInterface.sol"; import "../external/interfaces/WETH9Interface.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import { BridgeHubInterface } from "../interfaces/ZkStackBridgeHub.sol"; import { CircleCCTPAdapter } from "../libraries/CircleCCTPAdapter.sol"; import { ITokenMessenger } from "../external/interfaces/CCTPInterfaces.sol"; diff --git a/contracts/chain-adapters/ZkSync_Adapter.sol b/contracts/chain-adapters/ZkSync_Adapter.sol index 0826ece0a..8976a0b13 100644 --- a/contracts/chain-adapters/ZkSync_Adapter.sol +++ b/contracts/chain-adapters/ZkSync_Adapter.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.0; import "./interfaces/AdapterInterface.sol"; import "../external/interfaces/WETH9Interface.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; interface ZkSyncInterface { // _contractL2: L2 address of the contract to be called. @@ -171,11 +171,7 @@ contract ZkSync_Adapter is AdapterInterface { * @param _l2RefundAddress address that recieves excess gas refunds on L2. * @param _maxTxGasPrice The maximum effective gas price any transaction sent to this adapter may have. */ - constructor( - WETH9Interface _l1Weth, - address _l2RefundAddress, - uint256 _maxTxGasPrice - ) { + constructor(WETH9Interface _l1Weth, address _l2RefundAddress, uint256 _maxTxGasPrice) { l1Weth = _l1Weth; l2RefundAddress = _l2RefundAddress; MAX_TX_GASPRICE = _maxTxGasPrice; diff --git a/contracts/chain-adapters/Zora_Adapter.sol b/contracts/chain-adapters/Zora_Adapter.sol index d0de83ceb..188f12aec 100644 --- a/contracts/chain-adapters/Zora_Adapter.sol +++ b/contracts/chain-adapters/Zora_Adapter.sol @@ -9,8 +9,8 @@ import "../external/interfaces/WETH9Interface.sol"; import "./CrossDomainEnabled.sol"; import "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import "../libraries/CircleCCTPAdapter.sol"; import "../external/interfaces/CCTPInterfaces.sol"; @@ -75,12 +75,7 @@ contract Zora_Adapter is CrossDomainEnabled, AdapterInterface, CircleCCTPAdapter * @param amount Amount of L1 tokens to deposit and L2 tokens to receive. * @param to Bridge recipient. */ - function relayTokens( - address l1Token, - address l2Token, - uint256 amount, - address to - ) external payable override { + function relayTokens(address l1Token, address l2Token, uint256 amount, address to) external payable override { // If the l1Token is weth then unwrap it to ETH then send the ETH to the standard bridge. if (l1Token == address(L1_WETH)) { L1_WETH.withdraw(amount); diff --git a/contracts/chain-adapters/l2/Arbitrum_WithdrawalHelper.sol b/contracts/chain-adapters/l2/Arbitrum_WithdrawalHelper.sol index c4416d7d5..a04ffe530 100644 --- a/contracts/chain-adapters/l2/Arbitrum_WithdrawalHelper.sol +++ b/contracts/chain-adapters/l2/Arbitrum_WithdrawalHelper.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import { SafeERC20 } from "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import { ArbitrumL2ERC20GatewayLike } from "../../interfaces/ArbitrumBridge.sol"; import { WithdrawalHelperBase } from "./WithdrawalHelperBase.sol"; import { ITokenMessenger } from "../../external/interfaces/CCTPInterfaces.sol"; @@ -62,11 +62,7 @@ contract Arbitrum_WithdrawalHelper is WithdrawalHelperBase { * @param l2Token Address of the L2 token to send back. * @param amountToReturn Amount of l2Token to send back. */ - function withdrawToken( - address l1Token, - address l2Token, - uint256 amountToReturn - ) public override { + function withdrawToken(address l1Token, address l2Token, uint256 amountToReturn) public override { // If the l2TokenAddress is UDSC, we need to use the CCTP bridge. if (l2Token == address(usdcToken) && _isCCTPEnabled()) { _transferUsdc(TOKEN_RECIPIENT, amountToReturn); diff --git a/contracts/chain-adapters/l2/Ovm_WithdrawalHelper.sol b/contracts/chain-adapters/l2/Ovm_WithdrawalHelper.sol index 68aab32ba..c42da08bc 100644 --- a/contracts/chain-adapters/l2/Ovm_WithdrawalHelper.sol +++ b/contracts/chain-adapters/l2/Ovm_WithdrawalHelper.sol @@ -2,12 +2,12 @@ pragma solidity ^0.8.0; import { WithdrawalHelperBase } from "./WithdrawalHelperBase.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import { SafeERC20 } from "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import { WETH9Interface } from "../../external/interfaces/WETH9Interface.sol"; import { ITokenMessenger } from "../../external/interfaces/CCTPInterfaces.sol"; import { Lib_PredeployAddresses } from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol"; -import { LibOptimismUpgradeable } from "@openzeppelin/contracts-upgradeable/crosschain/optimism/LibOptimismUpgradeable.sol"; +import { LibOptimismUpgradeable } from "@openzeppelin/contracts-upgradeable-v4/crosschain/optimism/LibOptimismUpgradeable.sol"; import { IL2ERC20Bridge } from "../../Ovm_SpokePool.sol"; /** @@ -102,11 +102,7 @@ contract Ovm_WithdrawalHelper is WithdrawalHelperBase { * New lines of code correspond to instances where this contract queries state from the spoke pool, such as determining * the appropriate token bridge for the withdrawal or finding the remoteL1Token to withdraw. */ - function withdrawToken( - address, - address l2Token, - uint256 amountToReturn - ) public override { + function withdrawToken(address, address l2Token, uint256 amountToReturn) public override { // Fetch the current l1Gas defined in the Ovm_SpokePool. uint32 l1Gas = spokePool.l1Gas(); // If the token being bridged is WETH then we need to first unwrap it to ETH and then send ETH over the diff --git a/contracts/chain-adapters/l2/WithdrawalHelperBase.sol b/contracts/chain-adapters/l2/WithdrawalHelperBase.sol index f8de7a86d..e75be0e84 100644 --- a/contracts/chain-adapters/l2/WithdrawalHelperBase.sol +++ b/contracts/chain-adapters/l2/WithdrawalHelperBase.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { MultiCaller } from "@uma/core/contracts/common/implementation/MultiCaller.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import { MultiCaller } from "../../external/uma/core/contracts/common/implementation/MultiCaller.sol"; import { CircleCCTPAdapter, ITokenMessenger, CircleDomainIds } from "../../libraries/CircleCCTPAdapter.sol"; import { WETH9Interface } from "../../external/interfaces/WETH9Interface.sol"; -import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable-v4/proxy/utils/UUPSUpgradeable.sol"; /** * @title WithdrawalHelperBase @@ -102,11 +102,7 @@ abstract contract WithdrawalHelperBase is CircleCCTPAdapter, MultiCaller, UUPSUp * L1/L2 given knowledge of only one of the addresses. Both arguments are provided to enable a flexible interface; however, due * to this, `withdrawToken` MUST account for situations where the L1/L2 token mapping is incorrect. */ - function withdrawToken( - address l1Token, - address l2Token, - uint256 amountToReturn - ) public virtual; + function withdrawToken(address l1Token, address l2Token, uint256 amountToReturn) public virtual; /* * @notice Wraps the contract's entire balance of the native token. diff --git a/contracts/erc1155/MintableERC1155.sol b/contracts/erc1155/MintableERC1155.sol index 7603c9b4d..7df725fca 100644 --- a/contracts/erc1155/MintableERC1155.sol +++ b/contracts/erc1155/MintableERC1155.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import "@openzeppelin/contracts/access/Ownable.sol"; -import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; +import "@openzeppelin/contracts-v4/access/Ownable.sol"; +import "@openzeppelin/contracts-v4/token/ERC1155/ERC1155.sol"; /** * @title MintableERC1155 @@ -26,11 +26,7 @@ contract MintableERC1155 is ERC1155, Ownable { * @param tokenId Token type to airdrop. * @param amount Amount of token types to airdrop. */ - function airdrop( - uint256 tokenId, - address[] memory recipients, - uint256 amount - ) public onlyOwner { + function airdrop(uint256 tokenId, address[] memory recipients, uint256 amount) public onlyOwner { for (uint256 i = 0; i < recipients.length; i++) { _mint(recipients[i], tokenId, amount, ""); } diff --git a/contracts/erc7683/AcrossOriginSettler.sol b/contracts/erc7683/AcrossOriginSettler.sol index 39b6a061e..067a521f4 100644 --- a/contracts/erc7683/AcrossOriginSettler.sol +++ b/contracts/erc7683/AcrossOriginSettler.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/access/Ownable.sol"; import { ERC7683OrderDepositor } from "./ERC7683OrderDepositor.sol"; import "../SpokePool.sol"; import "../external/interfaces/IPermit2.sol"; -import "@uma/core/contracts/common/implementation/MultiCaller.sol"; +import "../external/uma/core/contracts/common/implementation/MultiCaller.sol"; /** * @notice AcrossOriginSettler processes an external order type and translates it into an AcrossV3Deposit diff --git a/contracts/erc7683/ERC7683OrderDepositor.sol b/contracts/erc7683/ERC7683OrderDepositor.sol index cfd97c5fd..d63d2a259 100644 --- a/contracts/erc7683/ERC7683OrderDepositor.sol +++ b/contracts/erc7683/ERC7683OrderDepositor.sol @@ -3,9 +3,9 @@ pragma solidity ^0.8.0; import "../external/interfaces/IPermit2.sol"; import { V3SpokePoolInterface } from "../interfaces/V3SpokePoolInterface.sol"; -import "@openzeppelin/contracts/utils/math/SafeCast.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/utils/math/SafeCast.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import { Output, GaslessCrossChainOrder, OnchainCrossChainOrder, ResolvedCrossChainOrder, IOriginSettler, FillInstruction } from "./ERC7683.sol"; import { AcrossOrderData, AcrossOriginFillerData, ERC7683Permit2Lib, ACROSS_ORDER_DATA_TYPE_HASH } from "./ERC7683Permit2Lib.sol"; @@ -122,11 +122,10 @@ abstract contract ERC7683OrderDepositor is IOriginSettler { * @param order the ERC-7683 compliant order. * @param originFillerData Across-specific fillerData. */ - function resolveFor(GaslessCrossChainOrder calldata order, bytes calldata originFillerData) - public - view - returns (ResolvedCrossChainOrder memory resolvedOrder) - { + function resolveFor( + GaslessCrossChainOrder calldata order, + bytes calldata originFillerData + ) public view returns (ResolvedCrossChainOrder memory resolvedOrder) { (resolvedOrder, , ) = _resolveFor(order, originFillerData); } @@ -134,11 +133,9 @@ abstract contract ERC7683OrderDepositor is IOriginSettler { * @notice Constructs a ResolvedOrder from a CrossChainOrder. * @param order the ERC7683 compliant order. */ - function resolve(OnchainCrossChainOrder calldata order) - public - view - returns (ResolvedCrossChainOrder memory resolvedOrder) - { + function resolve( + OnchainCrossChainOrder calldata order + ) public view returns (ResolvedCrossChainOrder memory resolvedOrder) { (resolvedOrder, ) = _resolve(order); } @@ -149,11 +146,10 @@ abstract contract ERC7683OrderDepositor is IOriginSettler { * @return acrossOrderData decoded AcrossOrderData. * @return acrossOriginFillerData decoded AcrossOriginFillerData. */ - function decode(bytes memory orderData, bytes memory fillerData) - public - pure - returns (AcrossOrderData memory, AcrossOriginFillerData memory) - { + function decode( + bytes memory orderData, + bytes memory fillerData + ) public pure returns (AcrossOrderData memory, AcrossOriginFillerData memory) { return (abi.decode(orderData, (AcrossOrderData)), abi.decode(fillerData, (AcrossOriginFillerData))); } @@ -176,7 +172,10 @@ abstract contract ERC7683OrderDepositor is IOriginSettler { */ function computeDepositId(uint256 depositNonce, address depositor) public view virtual returns (uint256); - function _resolveFor(GaslessCrossChainOrder calldata order, bytes calldata fillerData) + function _resolveFor( + GaslessCrossChainOrder calldata order, + bytes calldata fillerData + ) internal view returns ( @@ -260,11 +259,9 @@ abstract contract ERC7683OrderDepositor is IOriginSettler { }); } - function _resolve(OnchainCrossChainOrder calldata order) - internal - view - returns (ResolvedCrossChainOrder memory resolvedOrder, AcrossOrderData memory acrossOrderData) - { + function _resolve( + OnchainCrossChainOrder calldata order + ) internal view returns (ResolvedCrossChainOrder memory resolvedOrder, AcrossOrderData memory acrossOrderData) { if (order.orderDataType != ACROSS_ORDER_DATA_TYPE_HASH) { revert WrongOrderDataType(); } diff --git a/contracts/external/uma/core/contracts/common/implementation/ExpandedERC20.sol b/contracts/external/uma/core/contracts/common/implementation/ExpandedERC20.sol new file mode 100644 index 000000000..c2253c6d8 --- /dev/null +++ b/contracts/external/uma/core/contracts/common/implementation/ExpandedERC20.sol @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts-v4/token/ERC20/ERC20.sol"; +import "./MultiRole.sol"; +import "../interfaces/ExpandedIERC20.sol"; + +/** + * @title An ERC20 with permissioned burning and minting. The contract deployer will initially + * be the owner who is capable of adding new roles. + */ +contract ExpandedERC20 is ExpandedIERC20, ERC20, MultiRole { + enum Roles { + // Can set the minter and burner. + Owner, + // Addresses that can mint new tokens. + Minter, + // Addresses that can burn tokens that address owns. + Burner + } + + uint8 _decimals; + + /** + * @notice Constructs the ExpandedERC20. + * @param _tokenName The name which describes the new token. + * @param _tokenSymbol The ticker abbreviation of the name. Ideally < 5 chars. + * @param _tokenDecimals The number of decimals to define token precision. + */ + constructor( + string memory _tokenName, + string memory _tokenSymbol, + uint8 _tokenDecimals + ) ERC20(_tokenName, _tokenSymbol) { + _decimals = _tokenDecimals; + _createExclusiveRole(uint256(Roles.Owner), uint256(Roles.Owner), msg.sender); + _createSharedRole(uint256(Roles.Minter), uint256(Roles.Owner), new address[](0)); + _createSharedRole(uint256(Roles.Burner), uint256(Roles.Owner), new address[](0)); + } + + function decimals() public view virtual override(ERC20) returns (uint8) { + return _decimals; + } + + /** + * @dev Mints `value` tokens to `recipient`, returning true on success. + * @param recipient address to mint to. + * @param value amount of tokens to mint. + * @return True if the mint succeeded, or False. + */ + function mint( + address recipient, + uint256 value + ) external override onlyRoleHolder(uint256(Roles.Minter)) returns (bool) { + _mint(recipient, value); + return true; + } + + /** + * @dev Burns `value` tokens owned by `msg.sender`. + * @param value amount of tokens to burn. + */ + function burn(uint256 value) external override onlyRoleHolder(uint256(Roles.Burner)) { + _burn(msg.sender, value); + } + + /** + * @dev Burns `value` tokens owned by `recipient`. + * @param recipient address to burn tokens from. + * @param value amount of tokens to burn. + * @return True if the burn succeeded, or False. + */ + function burnFrom( + address recipient, + uint256 value + ) external override onlyRoleHolder(uint256(Roles.Burner)) returns (bool) { + _burn(recipient, value); + return true; + } + + /** + * @notice Add Minter role to account. + * @dev The caller must have the Owner role. + * @param account The address to which the Minter role is added. + */ + function addMinter(address account) external virtual override { + addMember(uint256(Roles.Minter), account); + } + + /** + * @notice Add Burner role to account. + * @dev The caller must have the Owner role. + * @param account The address to which the Burner role is added. + */ + function addBurner(address account) external virtual override { + addMember(uint256(Roles.Burner), account); + } + + /** + * @notice Reset Owner role to account. + * @dev The caller must have the Owner role. + * @param account The new holder of the Owner role. + */ + function resetOwner(address account) external virtual override { + resetMember(uint256(Roles.Owner), account); + } +} diff --git a/contracts/external/uma/core/contracts/common/implementation/FixedPoint.sol b/contracts/external/uma/core/contracts/common/implementation/FixedPoint.sol new file mode 100644 index 000000000..1115bcebc --- /dev/null +++ b/contracts/external/uma/core/contracts/common/implementation/FixedPoint.sol @@ -0,0 +1,763 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts-v4/utils/math/SafeMath.sol"; +import "@openzeppelin/contracts-v4/utils/math/SignedSafeMath.sol"; + +/** + * @title Library for fixed point arithmetic on uints + */ +library FixedPoint { + using SafeMath for uint256; + using SignedSafeMath for int256; + + // Supports 18 decimals. E.g., 1e18 represents "1", 5e17 represents "0.5". + // For unsigned values: + // This can represent a value up to (2^256 - 1)/10^18 = ~10^59. 10^59 will be stored internally as uint256 10^77. + uint256 private constant FP_SCALING_FACTOR = 10 ** 18; + + // --------------------------------------- UNSIGNED ----------------------------------------------------------------------------- + struct Unsigned { + uint256 rawValue; + } + + /** + * @notice Constructs an `Unsigned` from an unscaled uint, e.g., `b=5` gets stored internally as `5*(10**18)`. + * @param a uint to convert into a FixedPoint. + * @return the converted FixedPoint. + */ + function fromUnscaledUint(uint256 a) internal pure returns (Unsigned memory) { + return Unsigned(a.mul(FP_SCALING_FACTOR)); + } + + /** + * @notice Whether `a` is equal to `b`. + * @param a a FixedPoint. + * @param b a uint256. + * @return True if equal, or False. + */ + function isEqual(Unsigned memory a, uint256 b) internal pure returns (bool) { + return a.rawValue == fromUnscaledUint(b).rawValue; + } + + /** + * @notice Whether `a` is equal to `b`. + * @param a a FixedPoint. + * @param b a FixedPoint. + * @return True if equal, or False. + */ + function isEqual(Unsigned memory a, Unsigned memory b) internal pure returns (bool) { + return a.rawValue == b.rawValue; + } + + /** + * @notice Whether `a` is greater than `b`. + * @param a a FixedPoint. + * @param b a FixedPoint. + * @return True if `a > b`, or False. + */ + function isGreaterThan(Unsigned memory a, Unsigned memory b) internal pure returns (bool) { + return a.rawValue > b.rawValue; + } + + /** + * @notice Whether `a` is greater than `b`. + * @param a a FixedPoint. + * @param b a uint256. + * @return True if `a > b`, or False. + */ + function isGreaterThan(Unsigned memory a, uint256 b) internal pure returns (bool) { + return a.rawValue > fromUnscaledUint(b).rawValue; + } + + /** + * @notice Whether `a` is greater than `b`. + * @param a a uint256. + * @param b a FixedPoint. + * @return True if `a > b`, or False. + */ + function isGreaterThan(uint256 a, Unsigned memory b) internal pure returns (bool) { + return fromUnscaledUint(a).rawValue > b.rawValue; + } + + /** + * @notice Whether `a` is greater than or equal to `b`. + * @param a a FixedPoint. + * @param b a FixedPoint. + * @return True if `a >= b`, or False. + */ + function isGreaterThanOrEqual(Unsigned memory a, Unsigned memory b) internal pure returns (bool) { + return a.rawValue >= b.rawValue; + } + + /** + * @notice Whether `a` is greater than or equal to `b`. + * @param a a FixedPoint. + * @param b a uint256. + * @return True if `a >= b`, or False. + */ + function isGreaterThanOrEqual(Unsigned memory a, uint256 b) internal pure returns (bool) { + return a.rawValue >= fromUnscaledUint(b).rawValue; + } + + /** + * @notice Whether `a` is greater than or equal to `b`. + * @param a a uint256. + * @param b a FixedPoint. + * @return True if `a >= b`, or False. + */ + function isGreaterThanOrEqual(uint256 a, Unsigned memory b) internal pure returns (bool) { + return fromUnscaledUint(a).rawValue >= b.rawValue; + } + + /** + * @notice Whether `a` is less than `b`. + * @param a a FixedPoint. + * @param b a FixedPoint. + * @return True if `a < b`, or False. + */ + function isLessThan(Unsigned memory a, Unsigned memory b) internal pure returns (bool) { + return a.rawValue < b.rawValue; + } + + /** + * @notice Whether `a` is less than `b`. + * @param a a FixedPoint. + * @param b a uint256. + * @return True if `a < b`, or False. + */ + function isLessThan(Unsigned memory a, uint256 b) internal pure returns (bool) { + return a.rawValue < fromUnscaledUint(b).rawValue; + } + + /** + * @notice Whether `a` is less than `b`. + * @param a a uint256. + * @param b a FixedPoint. + * @return True if `a < b`, or False. + */ + function isLessThan(uint256 a, Unsigned memory b) internal pure returns (bool) { + return fromUnscaledUint(a).rawValue < b.rawValue; + } + + /** + * @notice Whether `a` is less than or equal to `b`. + * @param a a FixedPoint. + * @param b a FixedPoint. + * @return True if `a <= b`, or False. + */ + function isLessThanOrEqual(Unsigned memory a, Unsigned memory b) internal pure returns (bool) { + return a.rawValue <= b.rawValue; + } + + /** + * @notice Whether `a` is less than or equal to `b`. + * @param a a FixedPoint. + * @param b a uint256. + * @return True if `a <= b`, or False. + */ + function isLessThanOrEqual(Unsigned memory a, uint256 b) internal pure returns (bool) { + return a.rawValue <= fromUnscaledUint(b).rawValue; + } + + /** + * @notice Whether `a` is less than or equal to `b`. + * @param a a uint256. + * @param b a FixedPoint. + * @return True if `a <= b`, or False. + */ + function isLessThanOrEqual(uint256 a, Unsigned memory b) internal pure returns (bool) { + return fromUnscaledUint(a).rawValue <= b.rawValue; + } + + /** + * @notice The minimum of `a` and `b`. + * @param a a FixedPoint. + * @param b a FixedPoint. + * @return the minimum of `a` and `b`. + */ + function min(Unsigned memory a, Unsigned memory b) internal pure returns (Unsigned memory) { + return a.rawValue < b.rawValue ? a : b; + } + + /** + * @notice The maximum of `a` and `b`. + * @param a a FixedPoint. + * @param b a FixedPoint. + * @return the maximum of `a` and `b`. + */ + function max(Unsigned memory a, Unsigned memory b) internal pure returns (Unsigned memory) { + return a.rawValue > b.rawValue ? a : b; + } + + /** + * @notice Adds two `Unsigned`s, reverting on overflow. + * @param a a FixedPoint. + * @param b a FixedPoint. + * @return the sum of `a` and `b`. + */ + function add(Unsigned memory a, Unsigned memory b) internal pure returns (Unsigned memory) { + return Unsigned(a.rawValue.add(b.rawValue)); + } + + /** + * @notice Adds an `Unsigned` to an unscaled uint, reverting on overflow. + * @param a a FixedPoint. + * @param b a uint256. + * @return the sum of `a` and `b`. + */ + function add(Unsigned memory a, uint256 b) internal pure returns (Unsigned memory) { + return add(a, fromUnscaledUint(b)); + } + + /** + * @notice Subtracts two `Unsigned`s, reverting on overflow. + * @param a a FixedPoint. + * @param b a FixedPoint. + * @return the difference of `a` and `b`. + */ + function sub(Unsigned memory a, Unsigned memory b) internal pure returns (Unsigned memory) { + return Unsigned(a.rawValue.sub(b.rawValue)); + } + + /** + * @notice Subtracts an unscaled uint256 from an `Unsigned`, reverting on overflow. + * @param a a FixedPoint. + * @param b a uint256. + * @return the difference of `a` and `b`. + */ + function sub(Unsigned memory a, uint256 b) internal pure returns (Unsigned memory) { + return sub(a, fromUnscaledUint(b)); + } + + /** + * @notice Subtracts an `Unsigned` from an unscaled uint256, reverting on overflow. + * @param a a uint256. + * @param b a FixedPoint. + * @return the difference of `a` and `b`. + */ + function sub(uint256 a, Unsigned memory b) internal pure returns (Unsigned memory) { + return sub(fromUnscaledUint(a), b); + } + + /** + * @notice Multiplies two `Unsigned`s, reverting on overflow. + * @dev This will "floor" the product. + * @param a a FixedPoint. + * @param b a FixedPoint. + * @return the product of `a` and `b`. + */ + function mul(Unsigned memory a, Unsigned memory b) internal pure returns (Unsigned memory) { + // There are two caveats with this computation: + // 1. Max output for the represented number is ~10^41, otherwise an intermediate value overflows. 10^41 is + // stored internally as a uint256 ~10^59. + // 2. Results that can't be represented exactly are truncated not rounded. E.g., 1.4 * 2e-18 = 2.8e-18, which + // would round to 3, but this computation produces the result 2. + // No need to use SafeMath because FP_SCALING_FACTOR != 0. + return Unsigned(a.rawValue.mul(b.rawValue) / FP_SCALING_FACTOR); + } + + /** + * @notice Multiplies an `Unsigned` and an unscaled uint256, reverting on overflow. + * @dev This will "floor" the product. + * @param a a FixedPoint. + * @param b a uint256. + * @return the product of `a` and `b`. + */ + function mul(Unsigned memory a, uint256 b) internal pure returns (Unsigned memory) { + return Unsigned(a.rawValue.mul(b)); + } + + /** + * @notice Multiplies two `Unsigned`s and "ceil's" the product, reverting on overflow. + * @param a a FixedPoint. + * @param b a FixedPoint. + * @return the product of `a` and `b`. + */ + function mulCeil(Unsigned memory a, Unsigned memory b) internal pure returns (Unsigned memory) { + uint256 mulRaw = a.rawValue.mul(b.rawValue); + uint256 mulFloor = mulRaw / FP_SCALING_FACTOR; + uint256 mod = mulRaw.mod(FP_SCALING_FACTOR); + if (mod != 0) { + return Unsigned(mulFloor.add(1)); + } else { + return Unsigned(mulFloor); + } + } + + /** + * @notice Multiplies an `Unsigned` and an unscaled uint256 and "ceil's" the product, reverting on overflow. + * @param a a FixedPoint. + * @param b a FixedPoint. + * @return the product of `a` and `b`. + */ + function mulCeil(Unsigned memory a, uint256 b) internal pure returns (Unsigned memory) { + // Since b is an uint, there is no risk of truncation and we can just mul it normally + return Unsigned(a.rawValue.mul(b)); + } + + /** + * @notice Divides one `Unsigned` by an `Unsigned`, reverting on overflow or division by 0. + * @dev This will "floor" the quotient. + * @param a a FixedPoint numerator. + * @param b a FixedPoint denominator. + * @return the quotient of `a` divided by `b`. + */ + function div(Unsigned memory a, Unsigned memory b) internal pure returns (Unsigned memory) { + // There are two caveats with this computation: + // 1. Max value for the number dividend `a` represents is ~10^41, otherwise an intermediate value overflows. + // 10^41 is stored internally as a uint256 10^59. + // 2. Results that can't be represented exactly are truncated not rounded. E.g., 2 / 3 = 0.6 repeating, which + // would round to 0.666666666666666667, but this computation produces the result 0.666666666666666666. + return Unsigned(a.rawValue.mul(FP_SCALING_FACTOR).div(b.rawValue)); + } + + /** + * @notice Divides one `Unsigned` by an unscaled uint256, reverting on overflow or division by 0. + * @dev This will "floor" the quotient. + * @param a a FixedPoint numerator. + * @param b a uint256 denominator. + * @return the quotient of `a` divided by `b`. + */ + function div(Unsigned memory a, uint256 b) internal pure returns (Unsigned memory) { + return Unsigned(a.rawValue.div(b)); + } + + /** + * @notice Divides one unscaled uint256 by an `Unsigned`, reverting on overflow or division by 0. + * @dev This will "floor" the quotient. + * @param a a uint256 numerator. + * @param b a FixedPoint denominator. + * @return the quotient of `a` divided by `b`. + */ + function div(uint256 a, Unsigned memory b) internal pure returns (Unsigned memory) { + return div(fromUnscaledUint(a), b); + } + + /** + * @notice Divides one `Unsigned` by an `Unsigned` and "ceil's" the quotient, reverting on overflow or division by 0. + * @param a a FixedPoint numerator. + * @param b a FixedPoint denominator. + * @return the quotient of `a` divided by `b`. + */ + function divCeil(Unsigned memory a, Unsigned memory b) internal pure returns (Unsigned memory) { + uint256 aScaled = a.rawValue.mul(FP_SCALING_FACTOR); + uint256 divFloor = aScaled.div(b.rawValue); + uint256 mod = aScaled.mod(b.rawValue); + if (mod != 0) { + return Unsigned(divFloor.add(1)); + } else { + return Unsigned(divFloor); + } + } + + /** + * @notice Divides one `Unsigned` by an unscaled uint256 and "ceil's" the quotient, reverting on overflow or division by 0. + * @param a a FixedPoint numerator. + * @param b a uint256 denominator. + * @return the quotient of `a` divided by `b`. + */ + function divCeil(Unsigned memory a, uint256 b) internal pure returns (Unsigned memory) { + // Because it is possible that a quotient gets truncated, we can't just call "Unsigned(a.rawValue.div(b))" + // similarly to mulCeil with a uint256 as the second parameter. Therefore we need to convert b into an Unsigned. + // This creates the possibility of overflow if b is very large. + return divCeil(a, fromUnscaledUint(b)); + } + + /** + * @notice Raises an `Unsigned` to the power of an unscaled uint256, reverting on overflow. E.g., `b=2` squares `a`. + * @dev This will "floor" the result. + * @param a a FixedPoint numerator. + * @param b a uint256 denominator. + * @return output is `a` to the power of `b`. + */ + function pow(Unsigned memory a, uint256 b) internal pure returns (Unsigned memory output) { + output = fromUnscaledUint(1); + for (uint256 i = 0; i < b; i = i.add(1)) { + output = mul(output, a); + } + } + + // ------------------------------------------------- SIGNED ------------------------------------------------------------- + // Supports 18 decimals. E.g., 1e18 represents "1", 5e17 represents "0.5". + // For signed values: + // This can represent a value up (or down) to +-(2^255 - 1)/10^18 = ~10^58. 10^58 will be stored internally as int256 10^76. + int256 private constant SFP_SCALING_FACTOR = 10 ** 18; + + struct Signed { + int256 rawValue; + } + + function fromSigned(Signed memory a) internal pure returns (Unsigned memory) { + require(a.rawValue >= 0, "Negative value provided"); + return Unsigned(uint256(a.rawValue)); + } + + function fromUnsigned(Unsigned memory a) internal pure returns (Signed memory) { + require(a.rawValue <= uint256(type(int256).max), "Unsigned too large"); + return Signed(int256(a.rawValue)); + } + + /** + * @notice Constructs a `Signed` from an unscaled int, e.g., `b=5` gets stored internally as `5*(10**18)`. + * @param a int to convert into a FixedPoint.Signed. + * @return the converted FixedPoint.Signed. + */ + function fromUnscaledInt(int256 a) internal pure returns (Signed memory) { + return Signed(a.mul(SFP_SCALING_FACTOR)); + } + + /** + * @notice Whether `a` is equal to `b`. + * @param a a FixedPoint.Signed. + * @param b a int256. + * @return True if equal, or False. + */ + function isEqual(Signed memory a, int256 b) internal pure returns (bool) { + return a.rawValue == fromUnscaledInt(b).rawValue; + } + + /** + * @notice Whether `a` is equal to `b`. + * @param a a FixedPoint.Signed. + * @param b a FixedPoint.Signed. + * @return True if equal, or False. + */ + function isEqual(Signed memory a, Signed memory b) internal pure returns (bool) { + return a.rawValue == b.rawValue; + } + + /** + * @notice Whether `a` is greater than `b`. + * @param a a FixedPoint.Signed. + * @param b a FixedPoint.Signed. + * @return True if `a > b`, or False. + */ + function isGreaterThan(Signed memory a, Signed memory b) internal pure returns (bool) { + return a.rawValue > b.rawValue; + } + + /** + * @notice Whether `a` is greater than `b`. + * @param a a FixedPoint.Signed. + * @param b an int256. + * @return True if `a > b`, or False. + */ + function isGreaterThan(Signed memory a, int256 b) internal pure returns (bool) { + return a.rawValue > fromUnscaledInt(b).rawValue; + } + + /** + * @notice Whether `a` is greater than `b`. + * @param a an int256. + * @param b a FixedPoint.Signed. + * @return True if `a > b`, or False. + */ + function isGreaterThan(int256 a, Signed memory b) internal pure returns (bool) { + return fromUnscaledInt(a).rawValue > b.rawValue; + } + + /** + * @notice Whether `a` is greater than or equal to `b`. + * @param a a FixedPoint.Signed. + * @param b a FixedPoint.Signed. + * @return True if `a >= b`, or False. + */ + function isGreaterThanOrEqual(Signed memory a, Signed memory b) internal pure returns (bool) { + return a.rawValue >= b.rawValue; + } + + /** + * @notice Whether `a` is greater than or equal to `b`. + * @param a a FixedPoint.Signed. + * @param b an int256. + * @return True if `a >= b`, or False. + */ + function isGreaterThanOrEqual(Signed memory a, int256 b) internal pure returns (bool) { + return a.rawValue >= fromUnscaledInt(b).rawValue; + } + + /** + * @notice Whether `a` is greater than or equal to `b`. + * @param a an int256. + * @param b a FixedPoint.Signed. + * @return True if `a >= b`, or False. + */ + function isGreaterThanOrEqual(int256 a, Signed memory b) internal pure returns (bool) { + return fromUnscaledInt(a).rawValue >= b.rawValue; + } + + /** + * @notice Whether `a` is less than `b`. + * @param a a FixedPoint.Signed. + * @param b a FixedPoint.Signed. + * @return True if `a < b`, or False. + */ + function isLessThan(Signed memory a, Signed memory b) internal pure returns (bool) { + return a.rawValue < b.rawValue; + } + + /** + * @notice Whether `a` is less than `b`. + * @param a a FixedPoint.Signed. + * @param b an int256. + * @return True if `a < b`, or False. + */ + function isLessThan(Signed memory a, int256 b) internal pure returns (bool) { + return a.rawValue < fromUnscaledInt(b).rawValue; + } + + /** + * @notice Whether `a` is less than `b`. + * @param a an int256. + * @param b a FixedPoint.Signed. + * @return True if `a < b`, or False. + */ + function isLessThan(int256 a, Signed memory b) internal pure returns (bool) { + return fromUnscaledInt(a).rawValue < b.rawValue; + } + + /** + * @notice Whether `a` is less than or equal to `b`. + * @param a a FixedPoint.Signed. + * @param b a FixedPoint.Signed. + * @return True if `a <= b`, or False. + */ + function isLessThanOrEqual(Signed memory a, Signed memory b) internal pure returns (bool) { + return a.rawValue <= b.rawValue; + } + + /** + * @notice Whether `a` is less than or equal to `b`. + * @param a a FixedPoint.Signed. + * @param b an int256. + * @return True if `a <= b`, or False. + */ + function isLessThanOrEqual(Signed memory a, int256 b) internal pure returns (bool) { + return a.rawValue <= fromUnscaledInt(b).rawValue; + } + + /** + * @notice Whether `a` is less than or equal to `b`. + * @param a an int256. + * @param b a FixedPoint.Signed. + * @return True if `a <= b`, or False. + */ + function isLessThanOrEqual(int256 a, Signed memory b) internal pure returns (bool) { + return fromUnscaledInt(a).rawValue <= b.rawValue; + } + + /** + * @notice The minimum of `a` and `b`. + * @param a a FixedPoint.Signed. + * @param b a FixedPoint.Signed. + * @return the minimum of `a` and `b`. + */ + function min(Signed memory a, Signed memory b) internal pure returns (Signed memory) { + return a.rawValue < b.rawValue ? a : b; + } + + /** + * @notice The maximum of `a` and `b`. + * @param a a FixedPoint.Signed. + * @param b a FixedPoint.Signed. + * @return the maximum of `a` and `b`. + */ + function max(Signed memory a, Signed memory b) internal pure returns (Signed memory) { + return a.rawValue > b.rawValue ? a : b; + } + + /** + * @notice Adds two `Signed`s, reverting on overflow. + * @param a a FixedPoint.Signed. + * @param b a FixedPoint.Signed. + * @return the sum of `a` and `b`. + */ + function add(Signed memory a, Signed memory b) internal pure returns (Signed memory) { + return Signed(a.rawValue.add(b.rawValue)); + } + + /** + * @notice Adds an `Signed` to an unscaled int, reverting on overflow. + * @param a a FixedPoint.Signed. + * @param b an int256. + * @return the sum of `a` and `b`. + */ + function add(Signed memory a, int256 b) internal pure returns (Signed memory) { + return add(a, fromUnscaledInt(b)); + } + + /** + * @notice Subtracts two `Signed`s, reverting on overflow. + * @param a a FixedPoint.Signed. + * @param b a FixedPoint.Signed. + * @return the difference of `a` and `b`. + */ + function sub(Signed memory a, Signed memory b) internal pure returns (Signed memory) { + return Signed(a.rawValue.sub(b.rawValue)); + } + + /** + * @notice Subtracts an unscaled int256 from an `Signed`, reverting on overflow. + * @param a a FixedPoint.Signed. + * @param b an int256. + * @return the difference of `a` and `b`. + */ + function sub(Signed memory a, int256 b) internal pure returns (Signed memory) { + return sub(a, fromUnscaledInt(b)); + } + + /** + * @notice Subtracts an `Signed` from an unscaled int256, reverting on overflow. + * @param a an int256. + * @param b a FixedPoint.Signed. + * @return the difference of `a` and `b`. + */ + function sub(int256 a, Signed memory b) internal pure returns (Signed memory) { + return sub(fromUnscaledInt(a), b); + } + + /** + * @notice Multiplies two `Signed`s, reverting on overflow. + * @dev This will "floor" the product. + * @param a a FixedPoint.Signed. + * @param b a FixedPoint.Signed. + * @return the product of `a` and `b`. + */ + function mul(Signed memory a, Signed memory b) internal pure returns (Signed memory) { + // There are two caveats with this computation: + // 1. Max output for the represented number is ~10^41, otherwise an intermediate value overflows. 10^41 is + // stored internally as an int256 ~10^59. + // 2. Results that can't be represented exactly are truncated not rounded. E.g., 1.4 * 2e-18 = 2.8e-18, which + // would round to 3, but this computation produces the result 2. + // No need to use SafeMath because SFP_SCALING_FACTOR != 0. + return Signed(a.rawValue.mul(b.rawValue) / SFP_SCALING_FACTOR); + } + + /** + * @notice Multiplies an `Signed` and an unscaled int256, reverting on overflow. + * @dev This will "floor" the product. + * @param a a FixedPoint.Signed. + * @param b an int256. + * @return the product of `a` and `b`. + */ + function mul(Signed memory a, int256 b) internal pure returns (Signed memory) { + return Signed(a.rawValue.mul(b)); + } + + /** + * @notice Multiplies two `Signed`s and "ceil's" the product, reverting on overflow. + * @param a a FixedPoint.Signed. + * @param b a FixedPoint.Signed. + * @return the product of `a` and `b`. + */ + function mulAwayFromZero(Signed memory a, Signed memory b) internal pure returns (Signed memory) { + int256 mulRaw = a.rawValue.mul(b.rawValue); + int256 mulTowardsZero = mulRaw / SFP_SCALING_FACTOR; + // Manual mod because SignedSafeMath doesn't support it. + int256 mod = mulRaw % SFP_SCALING_FACTOR; + if (mod != 0) { + bool isResultPositive = isLessThan(a, 0) == isLessThan(b, 0); + int256 valueToAdd = isResultPositive ? int256(1) : int256(-1); + return Signed(mulTowardsZero.add(valueToAdd)); + } else { + return Signed(mulTowardsZero); + } + } + + /** + * @notice Multiplies an `Signed` and an unscaled int256 and "ceil's" the product, reverting on overflow. + * @param a a FixedPoint.Signed. + * @param b a FixedPoint.Signed. + * @return the product of `a` and `b`. + */ + function mulAwayFromZero(Signed memory a, int256 b) internal pure returns (Signed memory) { + // Since b is an int, there is no risk of truncation and we can just mul it normally + return Signed(a.rawValue.mul(b)); + } + + /** + * @notice Divides one `Signed` by an `Signed`, reverting on overflow or division by 0. + * @dev This will "floor" the quotient. + * @param a a FixedPoint numerator. + * @param b a FixedPoint denominator. + * @return the quotient of `a` divided by `b`. + */ + function div(Signed memory a, Signed memory b) internal pure returns (Signed memory) { + // There are two caveats with this computation: + // 1. Max value for the number dividend `a` represents is ~10^41, otherwise an intermediate value overflows. + // 10^41 is stored internally as an int256 10^59. + // 2. Results that can't be represented exactly are truncated not rounded. E.g., 2 / 3 = 0.6 repeating, which + // would round to 0.666666666666666667, but this computation produces the result 0.666666666666666666. + return Signed(a.rawValue.mul(SFP_SCALING_FACTOR).div(b.rawValue)); + } + + /** + * @notice Divides one `Signed` by an unscaled int256, reverting on overflow or division by 0. + * @dev This will "floor" the quotient. + * @param a a FixedPoint numerator. + * @param b an int256 denominator. + * @return the quotient of `a` divided by `b`. + */ + function div(Signed memory a, int256 b) internal pure returns (Signed memory) { + return Signed(a.rawValue.div(b)); + } + + /** + * @notice Divides one unscaled int256 by an `Signed`, reverting on overflow or division by 0. + * @dev This will "floor" the quotient. + * @param a an int256 numerator. + * @param b a FixedPoint denominator. + * @return the quotient of `a` divided by `b`. + */ + function div(int256 a, Signed memory b) internal pure returns (Signed memory) { + return div(fromUnscaledInt(a), b); + } + + /** + * @notice Divides one `Signed` by an `Signed` and "ceil's" the quotient, reverting on overflow or division by 0. + * @param a a FixedPoint numerator. + * @param b a FixedPoint denominator. + * @return the quotient of `a` divided by `b`. + */ + function divAwayFromZero(Signed memory a, Signed memory b) internal pure returns (Signed memory) { + int256 aScaled = a.rawValue.mul(SFP_SCALING_FACTOR); + int256 divTowardsZero = aScaled.div(b.rawValue); + // Manual mod because SignedSafeMath doesn't support it. + int256 mod = aScaled % b.rawValue; + if (mod != 0) { + bool isResultPositive = isLessThan(a, 0) == isLessThan(b, 0); + int256 valueToAdd = isResultPositive ? int256(1) : int256(-1); + return Signed(divTowardsZero.add(valueToAdd)); + } else { + return Signed(divTowardsZero); + } + } + + /** + * @notice Divides one `Signed` by an unscaled int256 and "ceil's" the quotient, reverting on overflow or division by 0. + * @param a a FixedPoint numerator. + * @param b an int256 denominator. + * @return the quotient of `a` divided by `b`. + */ + function divAwayFromZero(Signed memory a, int256 b) internal pure returns (Signed memory) { + // Because it is possible that a quotient gets truncated, we can't just call "Signed(a.rawValue.div(b))" + // similarly to mulCeil with an int256 as the second parameter. Therefore we need to convert b into an Signed. + // This creates the possibility of overflow if b is very large. + return divAwayFromZero(a, fromUnscaledInt(b)); + } + + /** + * @notice Raises an `Signed` to the power of an unscaled uint256, reverting on overflow. E.g., `b=2` squares `a`. + * @dev This will "floor" the result. + * @param a a FixedPoint.Signed. + * @param b a uint256 (negative exponents are not allowed). + * @return output is `a` to the power of `b`. + */ + function pow(Signed memory a, uint256 b) internal pure returns (Signed memory output) { + output = fromUnscaledInt(1); + for (uint256 i = 0; i < b; i = i.add(1)) { + output = mul(output, a); + } + } +} diff --git a/contracts/external/uma/core/contracts/common/implementation/MultiCaller.sol b/contracts/external/uma/core/contracts/common/implementation/MultiCaller.sol new file mode 100644 index 000000000..a3794a129 --- /dev/null +++ b/contracts/external/uma/core/contracts/common/implementation/MultiCaller.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +// This contract is taken from Uniswap's multi call implementation (https://github.com/Uniswap/uniswap-v3-periphery/blob/main/contracts/base/Multicall.sol) +// and was modified to be solidity 0.8 compatible. Additionally, the method was restricted to only work with msg.value +// set to 0 to avoid any nasty attack vectors on function calls that use value sent with deposits. + +/// @title MultiCaller +/// @notice Enables calling multiple methods in a single call to the contract +contract MultiCaller { + function multicall(bytes[] calldata data) external returns (bytes[] memory results) { + results = new bytes[](data.length); + for (uint256 i = 0; i < data.length; i++) { + (bool success, bytes memory result) = address(this).delegatecall(data[i]); + + if (!success) { + // Next 5 lines from https://ethereum.stackexchange.com/a/83577 + if (result.length < 68) revert(); + assembly { + result := add(result, 0x04) + } + revert(abi.decode(result, (string))); + } + + results[i] = result; + } + } +} diff --git a/contracts/external/uma/core/contracts/common/implementation/MultiRole.sol b/contracts/external/uma/core/contracts/common/implementation/MultiRole.sol new file mode 100644 index 000000000..0a8bd2d9c --- /dev/null +++ b/contracts/external/uma/core/contracts/common/implementation/MultiRole.sol @@ -0,0 +1,241 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +library Exclusive { + struct RoleMembership { + address member; + } + + function isMember(RoleMembership storage roleMembership, address memberToCheck) internal view returns (bool) { + return roleMembership.member == memberToCheck; + } + + function resetMember(RoleMembership storage roleMembership, address newMember) internal { + require(newMember != address(0x0), "Cannot set an exclusive role to 0x0"); + roleMembership.member = newMember; + } + + function getMember(RoleMembership storage roleMembership) internal view returns (address) { + return roleMembership.member; + } + + function init(RoleMembership storage roleMembership, address initialMember) internal { + resetMember(roleMembership, initialMember); + } +} + +library Shared { + struct RoleMembership { + mapping(address => bool) members; + } + + function isMember(RoleMembership storage roleMembership, address memberToCheck) internal view returns (bool) { + return roleMembership.members[memberToCheck]; + } + + function addMember(RoleMembership storage roleMembership, address memberToAdd) internal { + require(memberToAdd != address(0x0), "Cannot add 0x0 to a shared role"); + roleMembership.members[memberToAdd] = true; + } + + function removeMember(RoleMembership storage roleMembership, address memberToRemove) internal { + roleMembership.members[memberToRemove] = false; + } + + function init(RoleMembership storage roleMembership, address[] memory initialMembers) internal { + for (uint256 i = 0; i < initialMembers.length; i++) { + addMember(roleMembership, initialMembers[i]); + } + } +} + +/** + * @title Base class to manage permissions for the derived class. + */ +abstract contract MultiRole { + using Exclusive for Exclusive.RoleMembership; + using Shared for Shared.RoleMembership; + + enum RoleType { + Invalid, + Exclusive, + Shared + } + + struct Role { + uint256 managingRole; + RoleType roleType; + Exclusive.RoleMembership exclusiveRoleMembership; + Shared.RoleMembership sharedRoleMembership; + } + + mapping(uint256 => Role) private roles; + + event ResetExclusiveMember(uint256 indexed roleId, address indexed newMember, address indexed manager); + event AddedSharedMember(uint256 indexed roleId, address indexed newMember, address indexed manager); + event RemovedSharedMember(uint256 indexed roleId, address indexed oldMember, address indexed manager); + + /** + * @notice Reverts unless the caller is a member of the specified roleId. + */ + modifier onlyRoleHolder(uint256 roleId) { + require(holdsRole(roleId, msg.sender), "Sender does not hold required role"); + _; + } + + /** + * @notice Reverts unless the caller is a member of the manager role for the specified roleId. + */ + modifier onlyRoleManager(uint256 roleId) { + require(holdsRole(roles[roleId].managingRole, msg.sender), "Can only be called by a role manager"); + _; + } + + /** + * @notice Reverts unless the roleId represents an initialized, exclusive roleId. + */ + modifier onlyExclusive(uint256 roleId) { + require(roles[roleId].roleType == RoleType.Exclusive, "Must be called on an initialized Exclusive role"); + _; + } + + /** + * @notice Reverts unless the roleId represents an initialized, shared roleId. + */ + modifier onlyShared(uint256 roleId) { + require(roles[roleId].roleType == RoleType.Shared, "Must be called on an initialized Shared role"); + _; + } + + /** + * @notice Whether `memberToCheck` is a member of roleId. + * @dev Reverts if roleId does not correspond to an initialized role. + * @param roleId the Role to check. + * @param memberToCheck the address to check. + * @return True if `memberToCheck` is a member of `roleId`. + */ + function holdsRole(uint256 roleId, address memberToCheck) public view returns (bool) { + Role storage role = roles[roleId]; + if (role.roleType == RoleType.Exclusive) { + return role.exclusiveRoleMembership.isMember(memberToCheck); + } else if (role.roleType == RoleType.Shared) { + return role.sharedRoleMembership.isMember(memberToCheck); + } + revert("Invalid roleId"); + } + + /** + * @notice Changes the exclusive role holder of `roleId` to `newMember`. + * @dev Reverts if the caller is not a member of the managing role for `roleId` or if `roleId` is not an + * initialized, ExclusiveRole. + * @param roleId the ExclusiveRole membership to modify. + * @param newMember the new ExclusiveRole member. + */ + function resetMember(uint256 roleId, address newMember) public onlyExclusive(roleId) onlyRoleManager(roleId) { + roles[roleId].exclusiveRoleMembership.resetMember(newMember); + emit ResetExclusiveMember(roleId, newMember, msg.sender); + } + + /** + * @notice Gets the current holder of the exclusive role, `roleId`. + * @dev Reverts if `roleId` does not represent an initialized, exclusive role. + * @param roleId the ExclusiveRole membership to check. + * @return the address of the current ExclusiveRole member. + */ + function getMember(uint256 roleId) public view onlyExclusive(roleId) returns (address) { + return roles[roleId].exclusiveRoleMembership.getMember(); + } + + /** + * @notice Adds `newMember` to the shared role, `roleId`. + * @dev Reverts if `roleId` does not represent an initialized, SharedRole or if the caller is not a member of the + * managing role for `roleId`. + * @param roleId the SharedRole membership to modify. + * @param newMember the new SharedRole member. + */ + function addMember(uint256 roleId, address newMember) public onlyShared(roleId) onlyRoleManager(roleId) { + roles[roleId].sharedRoleMembership.addMember(newMember); + emit AddedSharedMember(roleId, newMember, msg.sender); + } + + /** + * @notice Removes `memberToRemove` from the shared role, `roleId`. + * @dev Reverts if `roleId` does not represent an initialized, SharedRole or if the caller is not a member of the + * managing role for `roleId`. + * @param roleId the SharedRole membership to modify. + * @param memberToRemove the current SharedRole member to remove. + */ + function removeMember(uint256 roleId, address memberToRemove) public onlyShared(roleId) onlyRoleManager(roleId) { + roles[roleId].sharedRoleMembership.removeMember(memberToRemove); + emit RemovedSharedMember(roleId, memberToRemove, msg.sender); + } + + /** + * @notice Removes caller from the role, `roleId`. + * @dev Reverts if the caller is not a member of the role for `roleId` or if `roleId` is not an + * initialized, SharedRole. + * @param roleId the SharedRole membership to modify. + */ + function renounceMembership(uint256 roleId) public onlyShared(roleId) onlyRoleHolder(roleId) { + roles[roleId].sharedRoleMembership.removeMember(msg.sender); + emit RemovedSharedMember(roleId, msg.sender, msg.sender); + } + + /** + * @notice Reverts if `roleId` is not initialized. + */ + modifier onlyValidRole(uint256 roleId) { + require(roles[roleId].roleType != RoleType.Invalid, "Attempted to use an invalid roleId"); + _; + } + + /** + * @notice Reverts if `roleId` is initialized. + */ + modifier onlyInvalidRole(uint256 roleId) { + require(roles[roleId].roleType == RoleType.Invalid, "Cannot use a pre-existing role"); + _; + } + + /** + * @notice Internal method to initialize a shared role, `roleId`, which will be managed by `managingRoleId`. + * `initialMembers` will be immediately added to the role. + * @dev Should be called by derived contracts, usually at construction time. Will revert if the role is already + * initialized. + */ + function _createSharedRole( + uint256 roleId, + uint256 managingRoleId, + address[] memory initialMembers + ) internal onlyInvalidRole(roleId) { + Role storage role = roles[roleId]; + role.roleType = RoleType.Shared; + role.managingRole = managingRoleId; + role.sharedRoleMembership.init(initialMembers); + require( + roles[managingRoleId].roleType != RoleType.Invalid, + "Attempted to use an invalid role to manage a shared role" + ); + } + + /** + * @notice Internal method to initialize an exclusive role, `roleId`, which will be managed by `managingRoleId`. + * `initialMember` will be immediately added to the role. + * @dev Should be called by derived contracts, usually at construction time. Will revert if the role is already + * initialized. + */ + function _createExclusiveRole( + uint256 roleId, + uint256 managingRoleId, + address initialMember + ) internal onlyInvalidRole(roleId) { + Role storage role = roles[roleId]; + role.roleType = RoleType.Exclusive; + role.managingRole = managingRoleId; + role.exclusiveRoleMembership.init(initialMember); + require( + roles[managingRoleId].roleType != RoleType.Invalid, + "Attempted to use an invalid role to manage an exclusive role" + ); + } +} diff --git a/contracts/external/uma/core/contracts/common/implementation/Testable.sol b/contracts/external/uma/core/contracts/common/implementation/Testable.sol new file mode 100644 index 000000000..164f9d7fc --- /dev/null +++ b/contracts/external/uma/core/contracts/common/implementation/Testable.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +import "./Timer.sol"; + +/** + * @title Base class that provides time overrides, but only if being run in test mode. + */ +abstract contract Testable { + // If the contract is being run in production, then `timerAddress` will be the 0x0 address. + // Note: this variable should be set on construction and never modified. + address public timerAddress; + + /** + * @notice Constructs the Testable contract. Called by child contracts. + * @param _timerAddress Contract that stores the current time in a testing environment. + * Must be set to 0x0 for production environments that use live time. + */ + constructor(address _timerAddress) { + timerAddress = _timerAddress; + } + + /** + * @notice Reverts if not running in test mode. + */ + modifier onlyIfTest() { + require(timerAddress != address(0x0)); + _; + } + + /** + * @notice Sets the current time. + * @dev Will revert if not running in test mode. + * @param time timestamp to set current Testable time to. + */ + function setCurrentTime(uint256 time) external onlyIfTest { + Timer(timerAddress).setCurrentTime(time); + } + + /** + * @notice Gets the current time. Will return the last time set in `setCurrentTime` if running in test mode. + * Otherwise, it will return the block timestamp. + * @return uint for the current Testable timestamp. + */ + function getCurrentTime() public view virtual returns (uint256) { + if (timerAddress != address(0x0)) { + return Timer(timerAddress).getCurrentTime(); + } else { + return block.timestamp; // solhint-disable-line not-rely-on-time + } + } +} diff --git a/contracts/external/uma/core/contracts/common/implementation/Timer.sol b/contracts/external/uma/core/contracts/common/implementation/Timer.sol new file mode 100644 index 000000000..9d76f6602 --- /dev/null +++ b/contracts/external/uma/core/contracts/common/implementation/Timer.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +/** + * @title Universal store of current contract time for testing environments. + */ +contract Timer { + uint256 private currentTime; + + constructor() { + currentTime = block.timestamp; // solhint-disable-line not-rely-on-time + } + + /** + * @notice Sets the current time. + * @dev Will revert if not running in test mode. + * @param time timestamp to set `currentTime` to. + */ + function setCurrentTime(uint256 time) external { + currentTime = time; + } + + /** + * @notice Gets the currentTime variable set in the Timer. + * @return uint256 for the current Testable timestamp. + */ + function getCurrentTime() public view returns (uint256) { + return currentTime; + } +} diff --git a/contracts/external/uma/core/contracts/common/interfaces/AddressWhitelistInterface.sol b/contracts/external/uma/core/contracts/common/interfaces/AddressWhitelistInterface.sol new file mode 100644 index 000000000..939344588 --- /dev/null +++ b/contracts/external/uma/core/contracts/common/interfaces/AddressWhitelistInterface.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +interface AddressWhitelistInterface { + function addToWhitelist(address newElement) external; + + function removeFromWhitelist(address newElement) external; + + function isOnWhitelist(address newElement) external view returns (bool); + + function getWhitelist() external view returns (address[] memory); +} diff --git a/contracts/external/uma/core/contracts/common/interfaces/ExpandedIERC20.sol b/contracts/external/uma/core/contracts/common/interfaces/ExpandedIERC20.sol new file mode 100644 index 000000000..a56adffda --- /dev/null +++ b/contracts/external/uma/core/contracts/common/interfaces/ExpandedIERC20.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; + +/** + * @title ERC20 interface that includes burn and mint methods. + */ +abstract contract ExpandedIERC20 is IERC20 { + /** + * @notice Burns a specific amount of the caller's tokens. + * @dev Only burns the caller's tokens, so it is safe to leave this method permissionless. + */ + function burn(uint256 value) external virtual; + + /** + * @dev Burns `value` tokens owned by `recipient`. + * @param recipient address to burn tokens from. + * @param value amount of tokens to burn. + */ + function burnFrom(address recipient, uint256 value) external virtual returns (bool); + + /** + * @notice Mints tokens and adds them to the balance of the `to` address. + * @dev This method should be permissioned to only allow designated parties to mint tokens. + */ + function mint(address to, uint256 value) external virtual returns (bool); + + function addMinter(address account) external virtual; + + function addBurner(address account) external virtual; + + function resetOwner(address account) external virtual; +} diff --git a/contracts/external/uma/core/contracts/data-verification-mechanism/implementation/Constants.sol b/contracts/external/uma/core/contracts/data-verification-mechanism/implementation/Constants.sol new file mode 100644 index 000000000..490b70a00 --- /dev/null +++ b/contracts/external/uma/core/contracts/data-verification-mechanism/implementation/Constants.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +/** + * @title Stores common interface names used throughout the DVM by registration in the Finder. + */ +library OracleInterfaces { + bytes32 public constant Oracle = "Oracle"; + bytes32 public constant IdentifierWhitelist = "IdentifierWhitelist"; + bytes32 public constant Store = "Store"; + bytes32 public constant FinancialContractsAdmin = "FinancialContractsAdmin"; + bytes32 public constant Registry = "Registry"; + bytes32 public constant CollateralWhitelist = "CollateralWhitelist"; + bytes32 public constant OptimisticOracle = "OptimisticOracle"; + bytes32 public constant OptimisticOracleV2 = "OptimisticOracleV2"; + bytes32 public constant OptimisticOracleV3 = "OptimisticOracleV3"; + bytes32 public constant Bridge = "Bridge"; + bytes32 public constant GenericHandler = "GenericHandler"; + bytes32 public constant SkinnyOptimisticOracle = "SkinnyOptimisticOracle"; + bytes32 public constant ChildMessenger = "ChildMessenger"; + bytes32 public constant OracleHub = "OracleHub"; + bytes32 public constant OracleSpoke = "OracleSpoke"; +} + +/** + * @title Commonly re-used values for contracts associated with the OptimisticOracle. + */ +library OptimisticOracleConstraints { + // Any price request submitted to the OptimisticOracle must contain ancillary data no larger than this value. + // This value must be <= the Voting contract's `ancillaryBytesLimit` constant value otherwise it is possible + // that a price can be requested to the OptimisticOracle successfully, but cannot be resolved by the DVM which + // refuses to accept a price request made with ancillary data length over a certain size. + uint256 public constant ancillaryBytesLimit = 8192; +} diff --git a/contracts/external/uma/core/contracts/data-verification-mechanism/interfaces/FinderInterface.sol b/contracts/external/uma/core/contracts/data-verification-mechanism/interfaces/FinderInterface.sol new file mode 100644 index 000000000..8f544d418 --- /dev/null +++ b/contracts/external/uma/core/contracts/data-verification-mechanism/interfaces/FinderInterface.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +/** + * @title Provides addresses of the live contracts implementing certain interfaces. + * @dev Examples are the Oracle or Store interfaces. + */ +interface FinderInterface { + /** + * @notice Updates the address of the contract that implements `interfaceName`. + * @param interfaceName bytes32 encoding of the interface name that is either changed or registered. + * @param implementationAddress address of the deployed contract that implements the interface. + */ + function changeImplementationAddress(bytes32 interfaceName, address implementationAddress) external; + + /** + * @notice Gets the address of the contract that implements the given `interfaceName`. + * @param interfaceName queried interface. + * @return implementationAddress address of the deployed contract that implements the interface. + */ + function getImplementationAddress(bytes32 interfaceName) external view returns (address); +} diff --git a/contracts/external/uma/core/contracts/data-verification-mechanism/interfaces/IdentifierWhitelistInterface.sol b/contracts/external/uma/core/contracts/data-verification-mechanism/interfaces/IdentifierWhitelistInterface.sol new file mode 100644 index 000000000..f56e205ed --- /dev/null +++ b/contracts/external/uma/core/contracts/data-verification-mechanism/interfaces/IdentifierWhitelistInterface.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +/** + * @title Interface for whitelists of supported identifiers that the oracle can provide prices for. + */ +interface IdentifierWhitelistInterface { + /** + * @notice Adds the provided identifier as a supported identifier. + * @dev Price requests using this identifier will succeed after this call. + * @param identifier bytes32 encoding of the string identifier. Eg: BTC/USD. + */ + function addSupportedIdentifier(bytes32 identifier) external; + + /** + * @notice Removes the identifier from the whitelist. + * @dev Price requests using this identifier will no longer succeed after this call. + * @param identifier bytes32 encoding of the string identifier. Eg: BTC/USD. + */ + function removeSupportedIdentifier(bytes32 identifier) external; + + /** + * @notice Checks whether an identifier is on the whitelist. + * @param identifier bytes32 encoding of the string identifier. Eg: BTC/USD. + * @return bool if the identifier is supported (or not). + */ + function isIdentifierSupported(bytes32 identifier) external view returns (bool); +} diff --git a/contracts/external/uma/core/contracts/data-verification-mechanism/interfaces/StoreInterface.sol b/contracts/external/uma/core/contracts/data-verification-mechanism/interfaces/StoreInterface.sol new file mode 100644 index 000000000..74c3bfd63 --- /dev/null +++ b/contracts/external/uma/core/contracts/data-verification-mechanism/interfaces/StoreInterface.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "../../common/implementation/FixedPoint.sol"; + +/** + * @title Interface that allows financial contracts to pay oracle fees for their use of the system. + */ +interface StoreInterface { + /** + * @notice Pays Oracle fees in ETH to the store. + * @dev To be used by contracts whose margin currency is ETH. + */ + function payOracleFees() external payable; + + /** + * @notice Pays oracle fees in the margin currency, erc20Address, to the store. + * @dev To be used if the margin currency is an ERC20 token rather than ETH. + * @param erc20Address address of the ERC20 token used to pay the fee. + * @param amount number of tokens to transfer. An approval for at least this amount must exist. + */ + function payOracleFeesErc20(address erc20Address, FixedPoint.Unsigned calldata amount) external; + + /** + * @notice Computes the regular oracle fees that a contract should pay for a period. + * @param startTime defines the beginning time from which the fee is paid. + * @param endTime end time until which the fee is paid. + * @param pfc "profit from corruption", or the maximum amount of margin currency that a + * token sponsor could extract from the contract through corrupting the price feed in their favor. + * @return regularFee amount owed for the duration from start to end time for the given pfc. + * @return latePenalty for paying the fee after the deadline. + */ + function computeRegularFee( + uint256 startTime, + uint256 endTime, + FixedPoint.Unsigned calldata pfc + ) external view returns (FixedPoint.Unsigned memory regularFee, FixedPoint.Unsigned memory latePenalty); + + /** + * @notice Computes the final oracle fees that a contract should pay at settlement. + * @param currency token used to pay the final fee. + * @return finalFee amount due. + */ + function computeFinalFee(address currency) external view returns (FixedPoint.Unsigned memory); +} diff --git a/contracts/external/uma/core/contracts/merkle-distributor/implementation/MerkleDistributor.sol b/contracts/external/uma/core/contracts/merkle-distributor/implementation/MerkleDistributor.sol new file mode 100644 index 000000000..5e7528281 --- /dev/null +++ b/contracts/external/uma/core/contracts/merkle-distributor/implementation/MerkleDistributor.sol @@ -0,0 +1,241 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/utils/cryptography/MerkleProof.sol"; +import "@openzeppelin/contracts-v4/access/Ownable.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "./MerkleDistributorInterface.sol"; + +/** + * Inspired by: + * - https://github.com/pie-dao/vested-token-migration-app + * - https://github.com/Uniswap/merkle-distributor + * - https://github.com/balancer-labs/erc20-redeemable + * + * @title MerkleDistributor contract. + * @notice Allows an owner to distribute any reward ERC20 to claimants according to Merkle roots. The owner can specify + * multiple Merkle roots distributions with customized reward currencies. + * @dev The Merkle trees are not validated in any way, so the system assumes the contract owner behaves honestly. + */ +contract MerkleDistributor is MerkleDistributorInterface, Ownable { + using SafeERC20 for IERC20; + + // Windows are mapped to arbitrary indices. + mapping(uint256 => Window) public merkleWindows; + + // Index of next created Merkle root. + uint256 public nextCreatedIndex; + + // Track which accounts have claimed for each window index. + // Note: uses a packed array of bools for gas optimization on tracking certain claims. Copied from Uniswap's contract. + mapping(uint256 => mapping(uint256 => uint256)) private claimedBitMap; + + /**************************************** + * EVENTS + ****************************************/ + event Claimed( + address indexed caller, + uint256 windowIndex, + address indexed account, + uint256 accountIndex, + uint256 amount, + address indexed rewardToken + ); + event CreatedWindow( + uint256 indexed windowIndex, + uint256 rewardsDeposited, + address indexed rewardToken, + address owner + ); + event WithdrawRewards(address indexed owner, uint256 amount, address indexed currency); + event DeleteWindow(uint256 indexed windowIndex, address owner); + + /**************************** + * ADMIN FUNCTIONS + ****************************/ + + /** + * @notice Set merkle root for the next available window index and seed allocations. + * @notice Callable only by owner of this contract. Caller must have approved this contract to transfer + * `rewardsToDeposit` amount of `rewardToken` or this call will fail. Importantly, we assume that the + * owner of this contract correctly chooses an amount `rewardsToDeposit` that is sufficient to cover all + * claims within the `merkleRoot`. + * @param rewardsToDeposit amount of rewards to deposit to seed this allocation. + * @param rewardToken ERC20 reward token. + * @param merkleRoot merkle root describing allocation. + * @param ipfsHash hash of IPFS object, conveniently stored for clients + */ + function setWindow( + uint256 rewardsToDeposit, + address rewardToken, + bytes32 merkleRoot, + string calldata ipfsHash + ) external onlyOwner { + uint256 indexToSet = nextCreatedIndex; + nextCreatedIndex = indexToSet + 1; + + _setWindow(indexToSet, rewardsToDeposit, rewardToken, merkleRoot, ipfsHash); + } + + /** + * @notice Delete merkle root at window index. + * @dev Callable only by owner. Likely to be followed by a withdrawRewards call to clear contract state. + * @param windowIndex merkle root index to delete. + */ + function deleteWindow(uint256 windowIndex) external onlyOwner { + delete merkleWindows[windowIndex]; + emit DeleteWindow(windowIndex, msg.sender); + } + + /** + * @notice Emergency method that transfers rewards out of the contract if the contract was configured improperly. + * @dev Callable only by owner. + * @param rewardCurrency rewards to withdraw from contract. + * @param amount amount of rewards to withdraw. + */ + function withdrawRewards(IERC20 rewardCurrency, uint256 amount) external onlyOwner { + rewardCurrency.safeTransfer(msg.sender, amount); + emit WithdrawRewards(msg.sender, amount, address(rewardCurrency)); + } + + /**************************** + * NON-ADMIN FUNCTIONS + ****************************/ + + /** + * @notice Batch claims to reduce gas versus individual submitting all claims. Method will fail + * if any individual claims within the batch would fail. + * @dev Optimistically tries to batch together consecutive claims for the same account and same + * reward token to reduce gas. Therefore, the most gas-cost-optimal way to use this method + * is to pass in an array of claims sorted by account and reward currency. It also reverts + * when any of individual `_claim`'s `amount` exceeds `remainingAmount` for its window. + * @param claims array of claims to claim. + */ + function claimMulti(Claim[] memory claims) public virtual override { + uint256 batchedAmount; + uint256 claimCount = claims.length; + for (uint256 i = 0; i < claimCount; i++) { + Claim memory _claim = claims[i]; + _verifyAndMarkClaimed(_claim); + batchedAmount += _claim.amount; + + // If the next claim is NOT the same account or the same token (or this claim is the last one), + // then disburse the `batchedAmount` to the current claim's account for the current claim's reward token. + uint256 nextI = i + 1; + IERC20 currentRewardToken = merkleWindows[_claim.windowIndex].rewardToken; + if ( + nextI == claimCount || + // This claim is last claim. + claims[nextI].account != _claim.account || + // Next claim account is different than current one. + merkleWindows[claims[nextI].windowIndex].rewardToken != currentRewardToken + // Next claim reward token is different than current one. + ) { + currentRewardToken.safeTransfer(_claim.account, batchedAmount); + batchedAmount = 0; + } + } + } + + /** + * @notice Claim amount of reward tokens for account, as described by Claim input object. + * @dev If the `_claim`'s `amount`, `accountIndex`, and `account` do not exactly match the + * values stored in the merkle root for the `_claim`'s `windowIndex` this method + * will revert. It also reverts when `_claim`'s `amount` exceeds `remainingAmount` for the window. + * @param _claim claim object describing amount, accountIndex, account, window index, and merkle proof. + */ + function claim(Claim memory _claim) public virtual override { + _verifyAndMarkClaimed(_claim); + merkleWindows[_claim.windowIndex].rewardToken.safeTransfer(_claim.account, _claim.amount); + } + + /** + * @notice Returns True if the claim for `accountIndex` has already been completed for the Merkle root at + * `windowIndex`. + * @dev This method will only work as intended if all `accountIndex`'s are unique for a given `windowIndex`. + * The onus is on the Owner of this contract to submit only valid Merkle roots. + * @param windowIndex merkle root to check. + * @param accountIndex account index to check within window index. + * @return True if claim has been executed already, False otherwise. + */ + function isClaimed(uint256 windowIndex, uint256 accountIndex) public view returns (bool) { + uint256 claimedWordIndex = accountIndex / 256; + uint256 claimedBitIndex = accountIndex % 256; + uint256 claimedWord = claimedBitMap[windowIndex][claimedWordIndex]; + uint256 mask = (1 << claimedBitIndex); + return claimedWord & mask == mask; + } + + /** + * @notice Returns rewardToken set by admin for windowIndex. + * @param windowIndex merkle root to check. + * @return address Reward token address + */ + function getRewardTokenForWindow(uint256 windowIndex) public view override returns (address) { + return address(merkleWindows[windowIndex].rewardToken); + } + + /** + * @notice Returns True if leaf described by {account, amount, accountIndex} is stored in Merkle root at given + * window index. + * @param _claim claim object describing amount, accountIndex, account, window index, and merkle proof. + * @return valid True if leaf exists. + */ + function verifyClaim(Claim memory _claim) public view returns (bool valid) { + bytes32 leaf = keccak256(abi.encodePacked(_claim.account, _claim.amount, _claim.accountIndex)); + return MerkleProof.verify(_claim.merkleProof, merkleWindows[_claim.windowIndex].merkleRoot, leaf); + } + + /**************************** + * PRIVATE FUNCTIONS + ****************************/ + + // Mark claim as completed for `accountIndex` for Merkle root at `windowIndex`. + function _setClaimed(uint256 windowIndex, uint256 accountIndex) private { + uint256 claimedWordIndex = accountIndex / 256; + uint256 claimedBitIndex = accountIndex % 256; + claimedBitMap[windowIndex][claimedWordIndex] = + claimedBitMap[windowIndex][claimedWordIndex] | + (1 << claimedBitIndex); + } + + // Store new Merkle root at `windowindex`. Pull `rewardsDeposited` from caller to seed distribution for this root. + function _setWindow( + uint256 windowIndex, + uint256 rewardsDeposited, + address rewardToken, + bytes32 merkleRoot, + string memory ipfsHash + ) private { + Window storage window = merkleWindows[windowIndex]; + window.merkleRoot = merkleRoot; + window.remainingAmount = rewardsDeposited; + window.rewardToken = IERC20(rewardToken); + window.ipfsHash = ipfsHash; + + emit CreatedWindow(windowIndex, rewardsDeposited, rewardToken, msg.sender); + + window.rewardToken.safeTransferFrom(msg.sender, address(this), rewardsDeposited); + } + + // Verify claim is valid and mark it as completed in this contract. + function _verifyAndMarkClaimed(Claim memory _claim) internal { + // Check claimed proof against merkle window at given index. + require(verifyClaim(_claim), "Incorrect merkle proof"); + // Check the account has not yet claimed for this window. + require(!isClaimed(_claim.windowIndex, _claim.accountIndex), "Account has already claimed for this window"); + + // Proof is correct and claim has not occurred yet, mark claimed complete. + _setClaimed(_claim.windowIndex, _claim.accountIndex); + merkleWindows[_claim.windowIndex].remainingAmount -= _claim.amount; + emit Claimed( + msg.sender, + _claim.windowIndex, + _claim.account, + _claim.accountIndex, + _claim.amount, + address(merkleWindows[_claim.windowIndex].rewardToken) + ); + } +} diff --git a/contracts/external/uma/core/contracts/merkle-distributor/implementation/MerkleDistributorInterface.sol b/contracts/external/uma/core/contracts/merkle-distributor/implementation/MerkleDistributorInterface.sol new file mode 100644 index 000000000..022c40cf9 --- /dev/null +++ b/contracts/external/uma/core/contracts/merkle-distributor/implementation/MerkleDistributorInterface.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-3.0-only +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; + +/** + * @notice Concise list of functions in MerkleDistributor implementation that would be called by + * a consuming external contract (such as the Across Protocol's AcceleratingDistributor). + */ +interface MerkleDistributorInterface { + // A Window maps a Merkle root to a reward token address. + struct Window { + // Merkle root describing the distribution. + bytes32 merkleRoot; + // Remaining amount of deposited rewards that have not yet been claimed. + uint256 remainingAmount; + // Currency in which reward is processed. + IERC20 rewardToken; + // IPFS hash of the merkle tree. Can be used to independently fetch recipient proofs and tree. Note that the canonical + // data type for storing an IPFS hash is a multihash which is the concatenation of + // . We opted to store this in a string type to make it easier + // for users to query the ipfs data without needing to reconstruct the multihash. to view the IPFS data simply + // go to https://cloudflare-ipfs.com/ipfs/. + string ipfsHash; + } + + // Represents an account's claim for `amount` within the Merkle root located at the `windowIndex`. + struct Claim { + uint256 windowIndex; + uint256 amount; + uint256 accountIndex; // Used only for bitmap. Assumed to be unique for each claim. + address account; + bytes32[] merkleProof; + } + + function claim(Claim memory _claim) external; + + function claimMulti(Claim[] memory claims) external; + + function getRewardTokenForWindow(uint256 windowIndex) external view returns (address); +} diff --git a/contracts/external/uma/core/contracts/optimistic-oracle-v2/interfaces/OptimisticOracleInterface.sol b/contracts/external/uma/core/contracts/optimistic-oracle-v2/interfaces/OptimisticOracleInterface.sol new file mode 100644 index 000000000..ef2a67e4b --- /dev/null +++ b/contracts/external/uma/core/contracts/optimistic-oracle-v2/interfaces/OptimisticOracleInterface.sol @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "../../data-verification-mechanism/interfaces/FinderInterface.sol"; + +/** + * @title Financial contract facing Oracle interface. + * @dev Interface used by financial contracts to interact with the Oracle. Voters will use a different interface. + */ +abstract contract OptimisticOracleInterface { + event RequestPrice( + address indexed requester, + bytes32 identifier, + uint256 timestamp, + bytes ancillaryData, + address currency, + uint256 reward, + uint256 finalFee + ); + event ProposePrice( + address indexed requester, + address indexed proposer, + bytes32 identifier, + uint256 timestamp, + bytes ancillaryData, + int256 proposedPrice, + uint256 expirationTimestamp, + address currency + ); + event DisputePrice( + address indexed requester, + address indexed proposer, + address indexed disputer, + bytes32 identifier, + uint256 timestamp, + bytes ancillaryData, + int256 proposedPrice + ); + event Settle( + address indexed requester, + address indexed proposer, + address indexed disputer, + bytes32 identifier, + uint256 timestamp, + bytes ancillaryData, + int256 price, + uint256 payout + ); + + // Struct representing the state of a price request. + enum State { + Invalid, // Never requested. + Requested, // Requested, no other actions taken. + Proposed, // Proposed, but not expired or disputed yet. + Expired, // Proposed, not disputed, past liveness. + Disputed, // Disputed, but no DVM price returned yet. + Resolved, // Disputed and DVM price is available. + Settled // Final price has been set in the contract (can get here from Expired or Resolved). + } + + // Struct representing a price request. + struct Request { + address proposer; // Address of the proposer. + address disputer; // Address of the disputer. + IERC20 currency; // ERC20 token used to pay rewards and fees. + bool settled; // True if the request is settled. + bool refundOnDispute; // True if the requester should be refunded their reward on dispute. + int256 proposedPrice; // Price that the proposer submitted. + int256 resolvedPrice; // Price resolved once the request is settled. + uint256 expirationTime; // Time at which the request auto-settles without a dispute. + uint256 reward; // Amount of the currency to pay to the proposer on settlement. + uint256 finalFee; // Final fee to pay to the Store upon request to the DVM. + uint256 bond; // Bond that the proposer and disputer must pay on top of the final fee. + uint256 customLiveness; // Custom liveness value set by the requester. + } + + // This value must be <= the Voting contract's `ancillaryBytesLimit` value otherwise it is possible + // that a price can be requested to this contract successfully, but cannot be disputed because the DVM refuses + // to accept a price request made with ancillary data length over a certain size. + uint256 public constant ancillaryBytesLimit = 8192; + + function defaultLiveness() external view virtual returns (uint256); + + function finder() external view virtual returns (FinderInterface); + + function getCurrentTime() external view virtual returns (uint256); + + // Note: this is required so that typechain generates a return value with named fields. + mapping(bytes32 => Request) public requests; + + /** + * @notice Requests a new price. + * @param identifier price identifier being requested. + * @param timestamp timestamp of the price being requested. + * @param ancillaryData ancillary data representing additional args being passed with the price request. + * @param currency ERC20 token used for payment of rewards and fees. Must be approved for use with the DVM. + * @param reward reward offered to a successful proposer. Will be pulled from the caller. Note: this can be 0, + * which could make sense if the contract requests and proposes the value in the same call or + * provides its own reward system. + * @return totalBond default bond (final fee) + final fee that the proposer and disputer will be required to pay. + * This can be changed with a subsequent call to setBond(). + */ + function requestPrice( + bytes32 identifier, + uint256 timestamp, + bytes memory ancillaryData, + IERC20 currency, + uint256 reward + ) external virtual returns (uint256 totalBond); + + /** + * @notice Set the proposal bond associated with a price request. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @param bond custom bond amount to set. + * @return totalBond new bond + final fee that the proposer and disputer will be required to pay. This can be + * changed again with a subsequent call to setBond(). + */ + function setBond( + bytes32 identifier, + uint256 timestamp, + bytes memory ancillaryData, + uint256 bond + ) external virtual returns (uint256 totalBond); + + /** + * @notice Sets the request to refund the reward if the proposal is disputed. This can help to "hedge" the caller + * in the event of a dispute-caused delay. Note: in the event of a dispute, the winner still receives the other's + * bond, so there is still profit to be made even if the reward is refunded. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + */ + function setRefundOnDispute(bytes32 identifier, uint256 timestamp, bytes memory ancillaryData) external virtual; + + /** + * @notice Sets a custom liveness value for the request. Liveness is the amount of time a proposal must wait before + * being auto-resolved. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @param customLiveness new custom liveness. + */ + function setCustomLiveness( + bytes32 identifier, + uint256 timestamp, + bytes memory ancillaryData, + uint256 customLiveness + ) external virtual; + + /** + * @notice Proposes a price value on another address' behalf. Note: this address will receive any rewards that come + * from this proposal. However, any bonds are pulled from the caller. + * @param proposer address to set as the proposer. + * @param requester sender of the initial price request. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @param proposedPrice price being proposed. + * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to + * the proposer once settled if the proposal is correct. + */ + function proposePriceFor( + address proposer, + address requester, + bytes32 identifier, + uint256 timestamp, + bytes memory ancillaryData, + int256 proposedPrice + ) public virtual returns (uint256 totalBond); + + /** + * @notice Proposes a price value for an existing price request. + * @param requester sender of the initial price request. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @param proposedPrice price being proposed. + * @return totalBond the amount that's pulled from the proposer's wallet as a bond. The bond will be returned to + * the proposer once settled if the proposal is correct. + */ + function proposePrice( + address requester, + bytes32 identifier, + uint256 timestamp, + bytes memory ancillaryData, + int256 proposedPrice + ) external virtual returns (uint256 totalBond); + + /** + * @notice Disputes a price request with an active proposal on another address' behalf. Note: this address will + * receive any rewards that come from this dispute. However, any bonds are pulled from the caller. + * @param disputer address to set as the disputer. + * @param requester sender of the initial price request. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to + * the disputer once settled if the dispute was value (the proposal was incorrect). + */ + function disputePriceFor( + address disputer, + address requester, + bytes32 identifier, + uint256 timestamp, + bytes memory ancillaryData + ) public virtual returns (uint256 totalBond); + + /** + * @notice Disputes a price value for an existing price request with an active proposal. + * @param requester sender of the initial price request. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @return totalBond the amount that's pulled from the disputer's wallet as a bond. The bond will be returned to + * the disputer once settled if the dispute was valid (the proposal was incorrect). + */ + function disputePrice( + address requester, + bytes32 identifier, + uint256 timestamp, + bytes memory ancillaryData + ) external virtual returns (uint256 totalBond); + + /** + * @notice Retrieves a price that was previously requested by a caller. Reverts if the request is not settled + * or settleable. Note: this method is not view so that this call may actually settle the price request if it + * hasn't been settled. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @return resolved price. + */ + function settleAndGetPrice( + bytes32 identifier, + uint256 timestamp, + bytes memory ancillaryData + ) external virtual returns (int256); + + /** + * @notice Attempts to settle an outstanding price request. Will revert if it isn't settleable. + * @param requester sender of the initial price request. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @return payout the amount that the "winner" (proposer or disputer) receives on settlement. This amount includes + * the returned bonds as well as additional rewards. + */ + function settle( + address requester, + bytes32 identifier, + uint256 timestamp, + bytes memory ancillaryData + ) external virtual returns (uint256 payout); + + /** + * @notice Gets the current data structure containing all information about a price request. + * @param requester sender of the initial price request. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @return the Request data structure. + */ + function getRequest( + address requester, + bytes32 identifier, + uint256 timestamp, + bytes memory ancillaryData + ) public view virtual returns (Request memory); + + /** + * @notice Returns the state of a price request. + * @param requester sender of the initial price request. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @return the State enum value. + */ + function getState( + address requester, + bytes32 identifier, + uint256 timestamp, + bytes memory ancillaryData + ) public view virtual returns (State); + + /** + * @notice Checks if a given request has resolved or been settled (i.e the optimistic oracle has a price). + * @param requester sender of the initial price request. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @return true if price has resolved or settled, false otherwise. + */ + function hasPrice( + address requester, + bytes32 identifier, + uint256 timestamp, + bytes memory ancillaryData + ) public view virtual returns (bool); + + function stampAncillaryData( + bytes memory ancillaryData, + address requester + ) public view virtual returns (bytes memory); +} diff --git a/contracts/external/uma/core/contracts/optimistic-oracle-v2/interfaces/SkinnyOptimisticOracleInterface.sol b/contracts/external/uma/core/contracts/optimistic-oracle-v2/interfaces/SkinnyOptimisticOracleInterface.sol new file mode 100644 index 000000000..ccea90ff7 --- /dev/null +++ b/contracts/external/uma/core/contracts/optimistic-oracle-v2/interfaces/SkinnyOptimisticOracleInterface.sol @@ -0,0 +1,250 @@ +// SPDX-License-Identifier: AGPL-3.0-only +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "../interfaces/OptimisticOracleInterface.sol"; + +/** + * @title Interface for the gas-cost-reduced version of the OptimisticOracle. + * @notice Differences from normal OptimisticOracle: + * - refundOnDispute: flag is removed, by default there are no refunds on disputes. + * - customizing request parameters: In the OptimisticOracle, parameters like `bond` and `customLiveness` can be reset + * after a request is already made via `requestPrice`. In the SkinnyOptimisticOracle, these parameters can only be + * set in `requestPrice`, which has an expanded input set. + * - settleAndGetPrice: Replaced by `settle`, which can only be called once per settleable request. The resolved price + * can be fetched via the `Settle` event or the return value of `settle`. + * - general changes to interface: Functions that interact with existing requests all require the parameters of the + * request to modify to be passed as input. These parameters must match with the existing request parameters or the + * function will revert. This change reflects the internal refactor to store hashed request parameters instead of the + * full request struct. + * @dev Interface used by financial contracts to interact with the Oracle. Voters will use a different interface. + */ +abstract contract SkinnyOptimisticOracleInterface { + // Struct representing a price request. Note that this differs from the OptimisticOracleInterface's Request struct + // in that refundOnDispute is removed. + struct Request { + address proposer; // Address of the proposer. + address disputer; // Address of the disputer. + IERC20 currency; // ERC20 token used to pay rewards and fees. + bool settled; // True if the request is settled. + int256 proposedPrice; // Price that the proposer submitted. + int256 resolvedPrice; // Price resolved once the request is settled. + uint256 expirationTime; // Time at which the request auto-settles without a dispute. + uint256 reward; // Amount of the currency to pay to the proposer on settlement. + uint256 finalFee; // Final fee to pay to the Store upon request to the DVM. + uint256 bond; // Bond that the proposer and disputer must pay on top of the final fee. + uint256 customLiveness; // Custom liveness value set by the requester. + } + + // This value must be <= the Voting contract's `ancillaryBytesLimit` value otherwise it is possible + // that a price can be requested to this contract successfully, but cannot be disputed because the DVM refuses + // to accept a price request made with ancillary data length over a certain size. + uint256 public constant ancillaryBytesLimit = 8192; + + /** + * @notice Requests a new price. + * @param identifier price identifier being requested. + * @param timestamp timestamp of the price being requested. + * @param ancillaryData ancillary data representing additional args being passed with the price request. + * @param currency ERC20 token used for payment of rewards and fees. Must be approved for use with the DVM. + * @param reward reward offered to a successful proposer. Will be pulled from the caller. Note: this can be 0, + * which could make sense if the contract requests and proposes the value in the same call or + * provides its own reward system. + * @param bond custom proposal bond to set for request. If set to 0, defaults to the final fee. + * @param customLiveness custom proposal liveness to set for request. + * @return totalBond default bond + final fee that the proposer and disputer will be required to pay. + */ + function requestPrice( + bytes32 identifier, + uint32 timestamp, + bytes memory ancillaryData, + IERC20 currency, + uint256 reward, + uint256 bond, + uint256 customLiveness + ) external virtual returns (uint256 totalBond); + + /** + * @notice Proposes a price value on another address' behalf. Note: this address will receive any rewards that come + * from this proposal. However, any bonds are pulled from the caller. + * @param requester sender of the initial price request. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @param request price request parameters whose hash must match the request that the caller wants to + * propose a price for. + * @param proposer address to set as the proposer. + * @param proposedPrice price being proposed. + * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to + * the proposer once settled if the proposal is correct. + */ + function proposePriceFor( + address requester, + bytes32 identifier, + uint32 timestamp, + bytes memory ancillaryData, + Request memory request, + address proposer, + int256 proposedPrice + ) public virtual returns (uint256 totalBond); + + /** + * @notice Proposes a price value where caller is the proposer. + * @param requester sender of the initial price request. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @param request price request parameters whose hash must match the request that the caller wants to + * propose a price for. + * @param proposedPrice price being proposed. + * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to + * the proposer once settled if the proposal is correct. + */ + function proposePrice( + address requester, + bytes32 identifier, + uint32 timestamp, + bytes memory ancillaryData, + Request memory request, + int256 proposedPrice + ) external virtual returns (uint256 totalBond); + + /** + * @notice Combines logic of requestPrice and proposePrice while taking advantage of gas savings from not having to + * overwrite Request params that a normal requestPrice() => proposePrice() flow would entail. Note: The proposer + * will receive any rewards that come from this proposal. However, any bonds are pulled from the caller. + * @dev The caller is the requester, but the proposer can be customized. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @param currency ERC20 token used for payment of rewards and fees. Must be approved for use with the DVM. + * @param reward reward offered to a successful proposer. Will be pulled from the caller. Note: this can be 0, + * which could make sense if the contract requests and proposes the value in the same call or + * provides its own reward system. + * @param bond custom proposal bond to set for request. If set to 0, defaults to the final fee. + * @param customLiveness custom proposal liveness to set for request. + * @param proposer address to set as the proposer. + * @param proposedPrice price being proposed. + * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to + * the proposer once settled if the proposal is correct. + */ + function requestAndProposePriceFor( + bytes32 identifier, + uint32 timestamp, + bytes memory ancillaryData, + IERC20 currency, + uint256 reward, + uint256 bond, + uint256 customLiveness, + address proposer, + int256 proposedPrice + ) external virtual returns (uint256 totalBond); + + /** + * @notice Disputes a price request with an active proposal on another address' behalf. Note: this address will + * receive any rewards that come from this dispute. However, any bonds are pulled from the caller. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @param request price request parameters whose hash must match the request that the caller wants to + * dispute. + * @param disputer address to set as the disputer. + * @param requester sender of the initial price request. + * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to + * the disputer once settled if the dispute was valid (the proposal was incorrect). + */ + function disputePriceFor( + bytes32 identifier, + uint32 timestamp, + bytes memory ancillaryData, + Request memory request, + address disputer, + address requester + ) public virtual returns (uint256 totalBond); + + /** + * @notice Disputes a price request with an active proposal where caller is the disputer. + * @param requester sender of the initial price request. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @param request price request parameters whose hash must match the request that the caller wants to + * dispute. + * @return totalBond the amount that's pulled from the caller's wallet as a bond. The bond will be returned to + * the disputer once settled if the dispute was valid (the proposal was incorrect). + */ + function disputePrice( + address requester, + bytes32 identifier, + uint32 timestamp, + bytes memory ancillaryData, + Request memory request + ) external virtual returns (uint256 totalBond); + + /** + * @notice Attempts to settle an outstanding price request. Will revert if it isn't settleable. + * @param requester sender of the initial price request. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @param request price request parameters whose hash must match the request that the caller wants to + * settle. + * @return payout the amount that the "winner" (proposer or disputer) receives on settlement. This amount includes + * the returned bonds as well as additional rewards. + * @return resolvedPrice the price that the request settled to. + */ + function settle( + address requester, + bytes32 identifier, + uint32 timestamp, + bytes memory ancillaryData, + Request memory request + ) external virtual returns (uint256 payout, int256 resolvedPrice); + + /** + * @notice Computes the current state of a price request. See the State enum for more details. + * @param requester sender of the initial price request. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @param request price request parameters. + * @return the State. + */ + function getState( + address requester, + bytes32 identifier, + uint32 timestamp, + bytes memory ancillaryData, + Request memory request + ) external virtual returns (OptimisticOracleInterface.State); + + /** + * @notice Checks if a given request has resolved, expired or been settled (i.e the optimistic oracle has a price). + * @param requester sender of the initial price request. + * @param identifier price identifier to identify the existing request. + * @param timestamp timestamp to identify the existing request. + * @param ancillaryData ancillary data of the price being requested. + * @param request price request parameters. The hash of these parameters must match with the request hash that is + * associated with the price request unique ID {requester, identifier, timestamp, ancillaryData}, or this method + * will revert. + * @return boolean indicating true if price exists and false if not. + */ + function hasPrice( + address requester, + bytes32 identifier, + uint32 timestamp, + bytes memory ancillaryData, + Request memory request + ) public virtual returns (bool); + + /** + * @notice Generates stamped ancillary data in the format that it would be used in the case of a price dispute. + * @param ancillaryData ancillary data of the price being requested. + * @param requester sender of the initial price request. + * @return the stamped ancillary bytes. + */ + function stampAncillaryData( + bytes memory ancillaryData, + address requester + ) public pure virtual returns (bytes memory); +} diff --git a/contracts/handlers/MulticallHandler.sol b/contracts/handlers/MulticallHandler.sol index c4af8bcc4..47d2841fe 100644 --- a/contracts/handlers/MulticallHandler.sol +++ b/contracts/handlers/MulticallHandler.sol @@ -2,10 +2,10 @@ pragma solidity ^0.8.0; import "../interfaces/SpokePoolMessageHandler.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import "@openzeppelin/contracts/utils/Address.sol"; -import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/utils/Address.sol"; +import "@openzeppelin/contracts-v4/security/ReentrancyGuard.sol"; /** * @title Across Multicall contract that allows a user to specify a series of calls that should be made by the handler diff --git a/contracts/interfaces/HubPoolInterface.sol b/contracts/interfaces/HubPoolInterface.sol index 128f906f5..7aca12679 100644 --- a/contracts/interfaces/HubPoolInterface.sol +++ b/contracts/interfaces/HubPoolInterface.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; /** * @notice Concise list of functions in HubPool implementation. @@ -106,11 +106,7 @@ interface HubPoolInterface { function setIdentifier(bytes32 newIdentifier) external; - function setCrossChainContracts( - uint256 l2ChainId, - address adapter, - address spokePool - ) external; + function setCrossChainContracts(uint256 l2ChainId, address adapter, address spokePool) external; function enableL1TokenForLiquidityProvision(address l1Token) external; @@ -118,11 +114,7 @@ interface HubPoolInterface { function addLiquidity(address l1Token, uint256 l1TokenAmount) external payable; - function removeLiquidity( - address l1Token, - uint256 lpTokenAmount, - bool sendEth - ) external; + function removeLiquidity(address l1Token, uint256 lpTokenAmount, bool sendEth) external; function exchangeRateCurrent(address l1Token) external returns (uint256); @@ -155,11 +147,7 @@ interface HubPoolInterface { function claimProtocolFeesCaptured(address l1Token) external; - function setPoolRebalanceRoute( - uint256 destinationChainId, - address l1Token, - address destinationToken - ) external; + function setPoolRebalanceRoute(uint256 destinationChainId, address l1Token, address destinationToken) external; function setDepositRoute( uint256 originChainId, @@ -168,10 +156,10 @@ interface HubPoolInterface { bool depositsEnabled ) external; - function poolRebalanceRoute(uint256 destinationChainId, address l1Token) - external - view - returns (address destinationToken); + function poolRebalanceRoute( + uint256 destinationChainId, + address l1Token + ) external view returns (address destinationToken); function loadEthForL2Calls() external payable; } diff --git a/contracts/interfaces/SpokePoolPeripheryInterface.sol b/contracts/interfaces/SpokePoolPeripheryInterface.sol index 680bf2256..823afc2e7 100644 --- a/contracts/interfaces/SpokePoolPeripheryInterface.sol +++ b/contracts/interfaces/SpokePoolPeripheryInterface.sol @@ -1,8 +1,8 @@ //SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { IERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import { IERC20Permit } from "@openzeppelin/contracts-v4/token/ERC20/extensions/IERC20Permit.sol"; import { IPermit2 } from "../external/interfaces/IPermit2.sol"; /** diff --git a/contracts/libraries/CircleCCTPAdapter.sol b/contracts/libraries/CircleCCTPAdapter.sol index a54ad9ae3..b68f79f58 100644 --- a/contracts/libraries/CircleCCTPAdapter.sol +++ b/contracts/libraries/CircleCCTPAdapter.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import "../external/interfaces/CCTPInterfaces.sol"; import { AddressToBytes32 } from "../libraries/AddressConverters.sol"; diff --git a/contracts/libraries/OFTTransportAdapter.sol b/contracts/libraries/OFTTransportAdapter.sol index 797dc7713..97a7acf28 100644 --- a/contracts/libraries/OFTTransportAdapter.sol +++ b/contracts/libraries/OFTTransportAdapter.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import { SafeERC20 } from "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import { IOFT, SendParam, MessagingFee, OFTReceipt } from "../interfaces/IOFT.sol"; import { AddressToBytes32 } from "../libraries/AddressConverters.sol"; diff --git a/contracts/merkle-distributor/AcrossMerkleDistributor.sol b/contracts/merkle-distributor/AcrossMerkleDistributor.sol index 3fde38ece..86a91990d 100644 --- a/contracts/merkle-distributor/AcrossMerkleDistributor.sol +++ b/contracts/merkle-distributor/AcrossMerkleDistributor.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import "@uma/core/contracts/merkle-distributor/implementation/MerkleDistributor.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "contracts/external/uma/core/contracts/merkle-distributor/implementation/MerkleDistributor.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; /** * @title Extended MerkleDistributor contract. diff --git a/contracts/permit2-order/Permit2Depositor.sol b/contracts/permit2-order/Permit2Depositor.sol index 6d512baca..783911d56 100644 --- a/contracts/permit2-order/Permit2Depositor.sol +++ b/contracts/permit2-order/Permit2Depositor.sol @@ -5,9 +5,9 @@ import "./Permit2OrderLib.sol"; import "../external/interfaces/IPermit2.sol"; import "../interfaces/V3SpokePoolInterface.sol"; -import "@openzeppelin/contracts/utils/math/SafeCast.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/utils/math/SafeCast.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; import { AddressToBytes32 } from "../libraries/AddressConverters.sol"; /** @@ -33,11 +33,7 @@ contract Permit2Depositor { * @param _permit2 Permit2 contract * @param _quoteBeforeDeadline quoteBeforeDeadline is subtracted from the deadline to get the quote timestamp. */ - constructor( - V3SpokePoolInterface _spokePool, - IPermit2 _permit2, - uint256 _quoteBeforeDeadline - ) { + constructor(V3SpokePoolInterface _spokePool, IPermit2 _permit2, uint256 _quoteBeforeDeadline) { SPOKE_POOL = _spokePool; PERMIT2 = _permit2; QUOTE_BEFORE_DEADLINE = _quoteBeforeDeadline; diff --git a/contracts/test/ExpandedERC20WithBlacklist.sol b/contracts/test/ExpandedERC20WithBlacklist.sol index 607609eb7..137488eab 100644 --- a/contracts/test/ExpandedERC20WithBlacklist.sol +++ b/contracts/test/ExpandedERC20WithBlacklist.sol @@ -1,26 +1,18 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "@uma/core/contracts/common/implementation/ExpandedERC20.sol"; +import "../external/uma/core/contracts/common/implementation/ExpandedERC20.sol"; contract ExpandedERC20WithBlacklist is ExpandedERC20 { mapping(address => bool) public isBlackListed; - constructor( - string memory name, - string memory symbol, - uint8 decimals - ) ExpandedERC20(name, symbol, decimals) {} + constructor(string memory name, string memory symbol, uint8 decimals) ExpandedERC20(name, symbol, decimals) {} function setBlacklistStatus(address account, bool status) external { isBlackListed[account] = status; } - function _beforeTokenTransfer( - address from, - address to, - uint256 amount - ) internal override { + function _beforeTokenTransfer(address from, address to, uint256 amount) internal override { require(!isBlackListed[to], "Recipient is blacklisted"); super._beforeTokenTransfer(from, to, amount); } diff --git a/contracts/test/MockERC1271.sol b/contracts/test/MockERC1271.sol index 3da5f2440..daf95884a 100644 --- a/contracts/test/MockERC1271.sol +++ b/contracts/test/MockERC1271.sol @@ -1,10 +1,10 @@ //SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; -import "@openzeppelin/contracts/interfaces/IERC1271.sol"; +import "@openzeppelin/contracts-v4/interfaces/IERC1271.sol"; -import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts-v4/utils/cryptography/ECDSA.sol"; +import "@openzeppelin/contracts-v4/access/Ownable.sol"; /** * @title MockERC1271 diff --git a/contracts/test/MockERC20.sol b/contracts/test/MockERC20.sol index 84150eee4..044f7d31e 100644 --- a/contracts/test/MockERC20.sol +++ b/contracts/test/MockERC20.sol @@ -2,9 +2,9 @@ pragma solidity ^0.8.0; import { IERC20Auth } from "../external/interfaces/IERC20Auth.sol"; -import { ERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { SignatureChecker } from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; +import { ERC20Permit } from "@openzeppelin/contracts-v4/token/ERC20/extensions/ERC20Permit.sol"; +import { ERC20 } from "@openzeppelin/contracts-v4/token/ERC20/ERC20.sol"; +import { SignatureChecker } from "@openzeppelin/contracts-v4/utils/cryptography/SignatureChecker.sol"; /** * @title MockERC20 diff --git a/contracts/test/MockPermit2.sol b/contracts/test/MockPermit2.sol index eac9d31b3..bbe413bf6 100644 --- a/contracts/test/MockPermit2.sol +++ b/contracts/test/MockPermit2.sol @@ -1,10 +1,10 @@ pragma solidity ^0.8.0; import { IPermit2 } from "../external/interfaces/IPermit2.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { IERC1271 } from "@openzeppelin/contracts/interfaces/IERC1271.sol"; -import { EIP712 } from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import { SafeERC20 } from "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; +import { IERC1271 } from "@openzeppelin/contracts-v4/interfaces/IERC1271.sol"; +import { EIP712 } from "@openzeppelin/contracts-v4/utils/cryptography/EIP712.sol"; // Taken from https://github.com/Uniswap/permit2/blob/main/src/EIP712.sol contract Permit2EIP712 { diff --git a/contracts/test/MockSpokePool.sol b/contracts/test/MockSpokePool.sol index cca9e449f..d592072bd 100644 --- a/contracts/test/MockSpokePool.sol +++ b/contracts/test/MockSpokePool.sol @@ -1,7 +1,7 @@ //SPDX-License-Identifier: Unlicense pragma solidity ^0.8.0; -import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable-v4/access/OwnableUpgradeable.sol"; import "../SpokePool.sol"; import "./interfaces/MockV2SpokePoolInterface.sol"; import "./V2MerkleLib.sol"; @@ -33,11 +33,7 @@ contract MockSpokePool is SpokePool, MockV2SpokePoolInterface, OwnableUpgradeabl /// @custom:oz-upgrades-unsafe-allow constructor constructor(address _wrappedNativeTokenAddress) SpokePool(_wrappedNativeTokenAddress, 1 hours, 9 hours, 0, 0) {} // solhint-disable-line no-empty-blocks - function initialize( - uint32 _initialDepositId, - address _crossDomainAdmin, - address _hubPool - ) public initializer { + function initialize(uint32 _initialDepositId, address _crossDomainAdmin, address _hubPool) public initializer { __Ownable_init(); __SpokePool_init(_initialDepositId, _crossDomainAdmin, _hubPool); currentTime = block.timestamp; // solhint-disable-line not-rely-on-time diff --git a/contracts/test/PolygonERC20Test.sol b/contracts/test/PolygonERC20Test.sol index a0b3d8b18..110128d4f 100644 --- a/contracts/test/PolygonERC20Test.sol +++ b/contracts/test/PolygonERC20Test.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import "@uma/core/contracts/common/implementation/ExpandedERC20.sol"; +import "../external/uma/core/contracts/common/implementation/ExpandedERC20.sol"; import "../PolygonTokenBridger.sol"; /** diff --git a/contracts/test/PolygonMocks.sol b/contracts/test/PolygonMocks.sol index 69fbf567e..09b18893f 100644 --- a/contracts/test/PolygonMocks.sol +++ b/contracts/test/PolygonMocks.sol @@ -1,16 +1,12 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/ERC20.sol"; contract RootChainManagerMock { function depositEtherFor(address user) external payable {} // solhint-disable-line no-empty-blocks - function depositFor( - address user, - address rootToken, - bytes calldata depositData - ) external {} // solhint-disable-line no-empty-blocks + function depositFor(address user, address rootToken, bytes calldata depositData) external {} // solhint-disable-line no-empty-blocks } contract FxStateSenderMock { diff --git a/contracts/test/V2MerkleLib.sol b/contracts/test/V2MerkleLib.sol index b18af96cb..0bc7ec48b 100644 --- a/contracts/test/V2MerkleLib.sol +++ b/contracts/test/V2MerkleLib.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; +import "@openzeppelin/contracts-v4/utils/cryptography/MerkleProof.sol"; import "./interfaces/MockV2SpokePoolInterface.sol"; /** diff --git a/contracts/upgradeable/AddressLibUpgradeable.sol b/contracts/upgradeable/AddressLibUpgradeable.sol index d5b5980d6..036a8d8ad 100644 --- a/contracts/upgradeable/AddressLibUpgradeable.sol +++ b/contracts/upgradeable/AddressLibUpgradeable.sol @@ -6,7 +6,7 @@ pragma solidity ^0.8.0; /** * @title AddressUpgradeable * @dev Collection of functions related to the address type - * @notice Logic is 100% copied from "@openzeppelin/contracts-upgradeable/contracts/utils/AddressUpgradeable.sol" but one + * @notice Logic is 100% copied from "@openzeppelin/contracts-upgradeable-v4/contracts/utils/AddressUpgradeable.sol" but one * comment is added to clarify why we allow delegatecall() in this contract, which is typically unsafe for use in * upgradeable implementation contracts. * @dev See https://docs.openzeppelin.com/upgrades-plugins/1.x/faq#delegatecall-selfdestruct for more details. @@ -121,11 +121,7 @@ library AddressLibUpgradeable { * * _Available since v3.1._ */ - function functionCallWithValue( - address target, - bytes memory data, - uint256 value - ) internal returns (bytes memory) { + function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } diff --git a/contracts/upgradeable/EIP712CrossChainUpgradeable.sol b/contracts/upgradeable/EIP712CrossChainUpgradeable.sol index de1f436de..5a5cef507 100644 --- a/contracts/upgradeable/EIP712CrossChainUpgradeable.sol +++ b/contracts/upgradeable/EIP712CrossChainUpgradeable.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import "@openzeppelin/contracts-upgradeable-v4/utils/cryptography/ECDSAUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable-v4/proxy/utils/Initializable.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. diff --git a/contracts/upgradeable/MultiCallerUpgradeable.sol b/contracts/upgradeable/MultiCallerUpgradeable.sol index 22b9e1dcb..32b6112d1 100644 --- a/contracts/upgradeable/MultiCallerUpgradeable.sol +++ b/contracts/upgradeable/MultiCallerUpgradeable.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; /** * @title MultiCallerUpgradeable - * @notice Logic is 100% copied from "@uma/core/contracts/common/implementation/MultiCaller.sol" but one + * @notice Logic is 100% copied from "contracts/external/uma/core/contracts/common/implementation/MultiCaller.sol" but one * comment is added to clarify why we allow delegatecall() in this contract, which is typically unsafe for use in * upgradeable implementation contracts. * @dev See https://docs.openzeppelin.com/upgrades-plugins/1.x/faq#delegatecall-selfdestruct for more details. diff --git a/foundry.toml b/foundry.toml index d5d2b5e6c..68f1ad17d 100644 --- a/foundry.toml +++ b/foundry.toml @@ -16,7 +16,6 @@ remappings = [ "@matterlabs/=node_modules/@matterlabs/", "@openzeppelin/=node_modules/@openzeppelin/", "@scroll-tech/=node_modules/@scroll-tech/", - "@uma/=node_modules/@uma/", "@uniswap/=node_modules/@uniswap/", "arb-bridge-eth/=node_modules/arb-bridge-eth/", "arb-bridge-peripherals/=node_modules/arb-bridge-peripherals/", @@ -28,11 +27,11 @@ remappings = [ ] via_ir = true optimizer_runs = 800 -solc_version = "0.8.23" +solc_version = "0.8.24" revert_strings = "strip" fs_permissions = [{ access = "read", path = "./"}] -solc = "0.8.23" +solc = "0.8.24" evm_version = "prague" [profile.zksync.zksync] diff --git a/hardhat.config.ts b/hardhat.config.ts index ddd7712a5..115e76bf0 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -56,7 +56,7 @@ const isTest = process.env.IS_TEST === "true" || process.env.CI === "true"; // the following config is true. const compileZk = process.env.COMPILE_ZK === "true"; -const solcVersion = "0.8.23"; +const solcVersion = "0.8.24"; // Compilation settings are overridden for large contracts to allow them to compile without going over the bytecode // limit. @@ -92,18 +92,7 @@ const config: HardhatUserConfig = { compilers: [DEFAULT_CONTRACT_COMPILER_SETTINGS], overrides: { "contracts/HubPool.sol": LARGE_CONTRACT_COMPILER_SETTINGS, - "contracts/Linea_SpokePool.sol": { - ...LARGE_CONTRACT_COMPILER_SETTINGS, - // NOTE: Linea only supports 0.8.19. - // See https://docs.linea.build/build-on-linea/ethereum-differences#evm-opcodes - version: "0.8.19", - }, - "contracts/SpokePoolVerifier.sol": { - ...DEFAULT_CONTRACT_COMPILER_SETTINGS, - // NOTE: Linea only supports 0.8.19. - // See https://docs.linea.build/build-on-linea/ethereum-differences#evm-opcodes - version: "0.8.19", - }, + "contracts/Linea_SpokePool.sol": LARGE_CONTRACT_COMPILER_SETTINGS, "contracts/Universal_SpokePool.sol": LARGE_CONTRACT_COMPILER_SETTINGS, "contracts/Arbitrum_SpokePool.sol": LARGE_CONTRACT_COMPILER_SETTINGS, "contracts/Scroll_SpokePool.sol": LARGE_CONTRACT_COMPILER_SETTINGS, diff --git a/package.json b/package.json index dbec6e189..27971fd9c 100644 --- a/package.json +++ b/package.json @@ -59,8 +59,10 @@ "@ethersproject/abstract-provider": "5.7.0", "@ethersproject/abstract-signer": "5.7.0", "@ethersproject/bignumber": "5.7.0", - "@openzeppelin/contracts": "4.9.6", - "@openzeppelin/contracts-upgradeable": "4.9.6", + "@openzeppelin/contracts": "5.5.0", + "@openzeppelin/contracts-upgradeable": "5.5.0", + "@openzeppelin/contracts-upgradeable-v4": "npm:@openzeppelin/contracts-upgradeable@4.9.6", + "@openzeppelin/contracts-v4": "npm:@openzeppelin/contracts@4.9.6", "@openzeppelin/foundry-upgrades": "^0.4.0", "@safe-global/protocol-kit": "^6.1.1", "@scroll-tech/contracts": "^0.1.0", @@ -73,7 +75,6 @@ "@types/yargs": "^17.0.33", "@uma/common": "^2.37.3", "@uma/contracts-node": "^0.4.17", - "@uma/core": "^2.61.0", "axios": "^1.7.4", "bs58": "^6.0.0", "prettier-plugin-rust": "^0.1.9", diff --git a/script/001DeployHubPool.s.sol b/script/001DeployHubPool.s.sol index ad98dbb23..a324a5ddc 100644 --- a/script/001DeployHubPool.s.sol +++ b/script/001DeployHubPool.s.sol @@ -6,7 +6,7 @@ import { Test } from "forge-std/Test.sol"; import { console } from "forge-std/console.sol"; import { HubPool } from "../contracts/HubPool.sol"; import { LpTokenFactory } from "../contracts/LpTokenFactory.sol"; -import { FinderInterface } from "@uma/core/contracts/data-verification-mechanism/interfaces/FinderInterface.sol"; +import { FinderInterface } from "contracts/external/uma/core/contracts/data-verification-mechanism/interfaces/FinderInterface.sol"; import { WETH9Interface } from "../contracts/external/interfaces/WETH9Interface.sol"; import { Constants } from "./utils/Constants.sol"; diff --git a/script/002DeployOptimismAdapter.s.sol b/script/002DeployOptimismAdapter.s.sol index e6c5aae90..b6e7f060c 100644 --- a/script/002DeployOptimismAdapter.s.sol +++ b/script/002DeployOptimismAdapter.s.sol @@ -6,7 +6,7 @@ import { Test } from "forge-std/Test.sol"; import { console } from "forge-std/console.sol"; import { Optimism_Adapter } from "../contracts/chain-adapters/Optimism_Adapter.sol"; import { Constants } from "./utils/Constants.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; import { ITokenMessenger } from "../contracts/external/interfaces/CCTPInterfaces.sol"; import { IL1StandardBridge } from "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; import { WETH9Interface } from "../contracts/external/interfaces/WETH9Interface.sol"; diff --git a/script/004DeployArbitrumAdapter.s.sol b/script/004DeployArbitrumAdapter.s.sol index 4b7f25b0b..5f4bbc456 100644 --- a/script/004DeployArbitrumAdapter.s.sol +++ b/script/004DeployArbitrumAdapter.s.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; import { Script } from "forge-std/Script.sol"; import { Test } from "forge-std/Test.sol"; import { console } from "forge-std/console.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; import { Arbitrum_Adapter } from "../contracts/chain-adapters/Arbitrum_Adapter.sol"; import { Constants } from "./utils/Constants.sol"; diff --git a/script/009DeployPolygonAdapter.s.sol b/script/009DeployPolygonAdapter.s.sol index bb8bfd64c..220db9603 100644 --- a/script/009DeployPolygonAdapter.s.sol +++ b/script/009DeployPolygonAdapter.s.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; import { Script } from "forge-std/Script.sol"; import { Test } from "forge-std/Test.sol"; import { console } from "forge-std/console.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; import { Polygon_Adapter } from "../contracts/chain-adapters/Polygon_Adapter.sol"; import { Constants } from "./utils/Constants.sol"; import { WETH9Interface } from "../contracts/external/interfaces/WETH9Interface.sol"; diff --git a/script/024DeployBaseAdapter.s.sol b/script/024DeployBaseAdapter.s.sol index 3cf0410e5..89a5cfebb 100644 --- a/script/024DeployBaseAdapter.s.sol +++ b/script/024DeployBaseAdapter.s.sol @@ -6,7 +6,7 @@ import { Test } from "forge-std/Test.sol"; import { console } from "forge-std/console.sol"; import { Base_Adapter } from "../contracts/chain-adapters/Base_Adapter.sol"; import { Constants } from "./utils/Constants.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; import { ITokenMessenger } from "../contracts/external/interfaces/CCTPInterfaces.sol"; import { IL1StandardBridge } from "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; import { WETH9Interface } from "../contracts/external/interfaces/WETH9Interface.sol"; diff --git a/script/061DeployUnichainAdapter.s.sol b/script/061DeployUnichainAdapter.s.sol index d5003f946..1c7b0841e 100644 --- a/script/061DeployUnichainAdapter.s.sol +++ b/script/061DeployUnichainAdapter.s.sol @@ -6,7 +6,7 @@ import { Test } from "forge-std/Test.sol"; import { console } from "forge-std/console.sol"; import { DoctorWho_Adapter as Unichain_Adapter } from "../contracts/chain-adapters/DoctorWho_Adapter.sol"; import { Constants } from "./utils/Constants.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; import { ITokenMessenger } from "../contracts/external/interfaces/CCTPInterfaces.sol"; import { IL1StandardBridge } from "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; import { WETH9Interface } from "../contracts/external/interfaces/WETH9Interface.sol"; diff --git a/script/utils/DeploymentUtils.sol b/script/utils/DeploymentUtils.sol index 61d569026..11b2fcc7d 100644 --- a/script/utils/DeploymentUtils.sol +++ b/script/utils/DeploymentUtils.sol @@ -6,7 +6,7 @@ import { Test } from "forge-std/Test.sol"; import { console } from "forge-std/console.sol"; import { Upgrades, Core, UnsafeUpgrades } from "@openzeppelin/foundry-upgrades/src/LegacyUpgrades.sol"; import { Options } from "@openzeppelin/foundry-upgrades/src/Options.sol"; -import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import { ERC1967Proxy } from "@openzeppelin/contracts-v4/proxy/ERC1967/ERC1967Proxy.sol"; import { Constants } from "./Constants.sol"; import { DeployedAddresses } from "./DeployedAddresses.sol"; diff --git a/test/evm/foundry/fork/BlacklistedRelayerRecipient.t.sol b/test/evm/foundry/fork/BlacklistedRelayerRecipient.t.sol index 65bbdbdb5..64a831672 100644 --- a/test/evm/foundry/fork/BlacklistedRelayerRecipient.t.sol +++ b/test/evm/foundry/fork/BlacklistedRelayerRecipient.t.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; import { Test } from "forge-std/Test.sol"; import { MockSpokePool } from "../../../../contracts/test/MockSpokePool.sol"; import { AddressToBytes32 } from "../../../../contracts/libraries/AddressConverters.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable-v4/token/ERC20/IERC20Upgradeable.sol"; // Define a minimal interface for USDT. Note USDT does NOT return anything after a transfer. interface IUSDT { @@ -12,11 +12,7 @@ interface IUSDT { function transfer(address recipient, uint256 amount) external; - function transferFrom( - address from, - address to, - uint256 value - ) external; + function transferFrom(address from, address to, uint256 value) external; function addBlackList(address _evilUser) external; @@ -29,11 +25,7 @@ interface IUSDC { function transfer(address recipient, uint256 amount) external returns (bool); - function transferFrom( - address from, - address to, - uint256 value - ) external returns (bool); + function transferFrom(address from, address to, uint256 value) external returns (bool); function blacklist(address _account) external; @@ -48,7 +40,7 @@ contract MockSpokePoolTest is Test { address largeUSDTAccount = 0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1; address largeUSDCAccount = 0x37305B1cD40574E4C5Ce33f8e8306Be057fD7341; - uint256 seedAmount = 10_000 * 10**6; + uint256 seedAmount = 10_000 * 10 ** 6; address recipient1 = address(0x6969691111111420); address recipient2 = address(0x6969692222222420); @@ -78,7 +70,7 @@ contract MockSpokePoolTest is Test { assertEq(usdt.balanceOf(address(spokePool)), seedAmount, "SpokePool should have seed USDT balance"); uint256[] memory refundAmounts = new uint256[](1); - refundAmounts[0] = 420 * 10**6; + refundAmounts[0] = 420 * 10 ** 6; address[] memory refundAddresses = new address[](1); refundAddresses[0] = recipient1; @@ -110,8 +102,8 @@ contract MockSpokePoolTest is Test { assertEq(usdt.balanceOf(recipient2), 0, "Recipient2 should start with 0 USDT balance"); uint256[] memory refundAmounts = new uint256[](2); - refundAmounts[0] = 420 * 10**6; - refundAmounts[1] = 69 * 10**6; + refundAmounts[0] = 420 * 10 ** 6; + refundAmounts[1] = 69 * 10 ** 6; address[] memory refundAddresses = new address[](2); refundAddresses[0] = recipient1; @@ -137,8 +129,8 @@ contract MockSpokePoolTest is Test { assertEq(usdc.balanceOf(recipient2), 0, "Recipient2 should start with 0 USDc balance"); uint256[] memory refundAmounts = new uint256[](2); - refundAmounts[0] = 420 * 10**6; - refundAmounts[1] = 69 * 10**6; + refundAmounts[0] = 420 * 10 ** 6; + refundAmounts[1] = 69 * 10 ** 6; address[] memory refundAddresses = new address[](2); refundAddresses[0] = recipient1; diff --git a/test/evm/foundry/fork/UniversalAdapterOFT.t.sol b/test/evm/foundry/fork/UniversalAdapterOFT.t.sol index bd9b94a55..5a8d496d0 100644 --- a/test/evm/foundry/fork/UniversalAdapterOFT.t.sol +++ b/test/evm/foundry/fork/UniversalAdapterOFT.t.sol @@ -8,8 +8,8 @@ import { Universal_Adapter } from "../../../../contracts/chain-adapters/Universa import { AdapterStore, MessengerTypes } from "../../../../contracts/AdapterStore.sol"; import { HubPoolStore } from "../../../../contracts/chain-adapters/utilities/HubPoolStore.sol"; import { IOFT, SendParam, MessagingFee } from "../../../../contracts/interfaces/IOFT.sol"; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import { ITokenMessenger } from "../../../../contracts/external/interfaces/CCTPInterfaces.sol"; // A mock contract to simulate the HubPool's delegatecall to the Universal_Adapter @@ -20,12 +20,7 @@ contract MockHub { adapter = _adapter; } - function callRelayTokens( - address l1Token, - address l2Token, - uint256 amount, - address to - ) external payable { + function callRelayTokens(address l1Token, address l2Token, uint256 amount, address to) external payable { // This simulates HubPool's delegatecall to the adapter (bool success, ) = adapter.delegatecall( abi.encodeWithSignature("relayTokens(address,address,uint256,address)", l1Token, l2Token, amount, to) @@ -60,7 +55,7 @@ contract UniversalAdapterOFTTest is Test { // Test parameters uint256 forkId; - uint256 constant SEND_AMOUNT = 1 * 10**6; // 1 USDT (6 decimals) + uint256 constant SEND_AMOUNT = 1 * 10 ** 6; // 1 USDT (6 decimals) uint256 constant ETH_FUNDING = 0.1 ether; uint32 constant DST_EID = 30110; // Arbitrum EID address constant RECIPIENT = 0x9A8f92a830A5cB89a3816e3D267CB7791c16b04D; // dev wallet diff --git a/test/evm/foundry/local/Blast_DaiRetriever.t.sol b/test/evm/foundry/local/Blast_DaiRetriever.t.sol index 71a93645b..2dfc10eab 100644 --- a/test/evm/foundry/local/Blast_DaiRetriever.t.sol +++ b/test/evm/foundry/local/Blast_DaiRetriever.t.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.0; import { Test } from "forge-std/Test.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; +import { ERC20 } from "@openzeppelin/contracts-v4/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts-upgradeable-v4/token/ERC20/IERC20Upgradeable.sol"; import { Blast_DaiRetriever } from "../../../../contracts/Blast_DaiRetriever.sol"; import { MockBlastUsdYieldManager } from "../../../../contracts/test/MockBlastUsdYieldManager.sol"; diff --git a/test/evm/foundry/local/Forwarder.t.sol b/test/evm/foundry/local/Forwarder.t.sol index a87874740..36f2023e5 100644 --- a/test/evm/foundry/local/Forwarder.t.sol +++ b/test/evm/foundry/local/Forwarder.t.sol @@ -3,10 +3,10 @@ pragma solidity ^0.8.0; import { Test } from "forge-std/Test.sol"; -import { ERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; +import { ERC20, IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/ERC20.sol"; +import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable-v4/token/ERC20/IERC20Upgradeable.sol"; import { IL1StandardBridge } from "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; -import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import { ERC1967Proxy } from "@openzeppelin/contracts-v4/proxy/ERC1967/ERC1967Proxy.sol"; import { Optimism_Adapter } from "../../../../contracts/chain-adapters/Optimism_Adapter.sol"; import { WETH9Interface } from "../../../../contracts/external/interfaces/WETH9Interface.sol"; diff --git a/test/evm/foundry/local/MultiCallerUpgradeable.t.sol b/test/evm/foundry/local/MultiCallerUpgradeable.t.sol index c50b87540..605ae03ca 100644 --- a/test/evm/foundry/local/MultiCallerUpgradeable.t.sol +++ b/test/evm/foundry/local/MultiCallerUpgradeable.t.sol @@ -6,8 +6,8 @@ import "forge-std/console.sol"; import { SpokePool } from "../../../../contracts/SpokePool.sol"; import { Ethereum_SpokePool } from "../../../../contracts/Ethereum_SpokePool.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { ERC20 } from "@openzeppelin/contracts-v4/token/ERC20/ERC20.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; import { AddressToBytes32 } from "../../../../contracts/libraries/AddressConverters.sol"; // This test does not require a mainnet fork (since it is testing contracts before deployment). @@ -35,13 +35,13 @@ contract MultiCallerUpgradeableTest is Test { rando2 = vm.addr(2); relayer = vm.addr(3); - deal(address(mockL2WETH), relayer, 10**22, true); + deal(address(mockL2WETH), relayer, 10 ** 22, true); vm.prank(relayer); - IERC20(address(mockL2WETH)).approve(address(ethereumSpokePool), 2**256 - 1); + IERC20(address(mockL2WETH)).approve(address(ethereumSpokePool), 2 ** 256 - 1); // Create Dummy Relay Data - uint256 depositAmount = 5 * (10**18); + uint256 depositAmount = 5 * (10 ** 18); uint256 mockRepaymentChainId = 1; uint32 fillDeadline = uint32(ethereumSpokePool.getCurrentTime()) + 1000; diff --git a/test/evm/foundry/local/MulticallHandler.t.sol b/test/evm/foundry/local/MulticallHandler.t.sol index b52d6c113..d6498602e 100644 --- a/test/evm/foundry/local/MulticallHandler.t.sol +++ b/test/evm/foundry/local/MulticallHandler.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import { Test } from "forge-std/Test.sol"; import { MulticallHandler } from "../../../../contracts/handlers/MulticallHandler.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; // Run this test to verify PermissionSplitter behavior when changing ownership of the HubPool // to it. Therefore this test should be run as a fork test via: diff --git a/test/evm/foundry/local/Router_Adapter.t.sol b/test/evm/foundry/local/Router_Adapter.t.sol index a415a9cad..1edd7e2d5 100644 --- a/test/evm/foundry/local/Router_Adapter.t.sol +++ b/test/evm/foundry/local/Router_Adapter.t.sol @@ -3,10 +3,10 @@ pragma solidity ^0.8.0; import { Test } from "forge-std/Test.sol"; -import { ERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; +import { ERC20, IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/ERC20.sol"; +import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable-v4/token/ERC20/IERC20Upgradeable.sol"; import { IL1StandardBridge } from "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; -import { FinderInterface } from "@uma/core/contracts/data-verification-mechanism/interfaces/FinderInterface.sol"; +import { FinderInterface } from "contracts/external/uma/core/contracts/data-verification-mechanism/interfaces/FinderInterface.sol"; import { Router_Adapter } from "../../../../contracts/chain-adapters/Router_Adapter.sol"; import { Optimism_Adapter } from "../../../../contracts/chain-adapters/Optimism_Adapter.sol"; diff --git a/test/evm/foundry/local/SpokePoolDeprecatedMethods.t.sol b/test/evm/foundry/local/SpokePoolDeprecatedMethods.t.sol index f47ed02b0..8d2ea918a 100644 --- a/test/evm/foundry/local/SpokePoolDeprecatedMethods.t.sol +++ b/test/evm/foundry/local/SpokePoolDeprecatedMethods.t.sol @@ -5,7 +5,7 @@ import { Test } from "forge-std/Test.sol"; import { MockSpokePool } from "../../../../contracts/test/MockSpokePool.sol"; import { WETH9 } from "../../../../contracts/external/WETH9.sol"; import { AddressToBytes32 } from "../../../../contracts/libraries/AddressConverters.sol"; -import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import { ERC1967Proxy } from "@openzeppelin/contracts-v4/proxy/ERC1967/ERC1967Proxy.sol"; // Deprecated interface used to show that we can still call deposit() on the spoke, which should route internally to the // colliding function interface selector on depositDeprecated_5947912356 enabling legacy deposits to still work without @@ -33,7 +33,7 @@ contract SpokePoolOverloadedDeprecatedMethodsTest is Test { address owner; uint256 destinationChainId = 10; - uint256 depositAmount = 0.5 * (10**18); + uint256 depositAmount = 0.5 * (10 ** 18); function setUp() public { mockWETH = new WETH9(); diff --git a/test/evm/foundry/local/SpokePoolPeriphery.t.sol b/test/evm/foundry/local/SpokePoolPeriphery.t.sol index 5a3398da4..fa21dcf2a 100644 --- a/test/evm/foundry/local/SpokePoolPeriphery.t.sol +++ b/test/evm/foundry/local/SpokePoolPeriphery.t.sol @@ -14,9 +14,9 @@ import { IPermit2 } from "../../../../contracts/external/interfaces/IPermit2.sol import { MockPermit2, Permit2EIP712, SignatureVerification } from "../../../../contracts/test/MockPermit2.sol"; import { PeripherySigningLib } from "../../../../contracts/libraries/PeripherySigningLib.sol"; import { MockERC20 } from "../../../../contracts/test/MockERC20.sol"; -import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { IERC1271 } from "@openzeppelin/contracts/interfaces/IERC1271.sol"; +import { ERC1967Proxy } from "@openzeppelin/contracts-v4/proxy/ERC1967/ERC1967Proxy.sol"; +import { IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; +import { IERC1271 } from "@openzeppelin/contracts-v4/interfaces/IERC1271.sol"; import { AddressToBytes32 } from "../../../../contracts/libraries/AddressConverters.sol"; contract Exchange { diff --git a/test/evm/foundry/local/SpokePoolVerifier.t.sol b/test/evm/foundry/local/SpokePoolVerifier.t.sol index 6aad99e01..3dd873788 100644 --- a/test/evm/foundry/local/SpokePoolVerifier.t.sol +++ b/test/evm/foundry/local/SpokePoolVerifier.t.sol @@ -7,8 +7,8 @@ import { SpokePoolVerifier } from "../../../../contracts/SpokePoolVerifier.sol"; import { Ethereum_SpokePool } from "../../../../contracts/Ethereum_SpokePool.sol"; import { V3SpokePoolInterface } from "../../../../contracts/interfaces/V3SpokePoolInterface.sol"; import { WETH9 } from "../../../../contracts/external/WETH9.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import { ERC20 } from "@openzeppelin/contracts-v4/token/ERC20/ERC20.sol"; +import { ERC1967Proxy } from "@openzeppelin/contracts-v4/proxy/ERC1967/ERC1967Proxy.sol"; import { AddressToBytes32 } from "../../../../contracts/libraries/AddressConverters.sol"; interface EthereumSpokePoolOnlyAddressInterface { @@ -41,8 +41,8 @@ contract SpokePoolVerifierTest is Test { address owner; uint256 destinationChainId = 10; - uint256 mintAmount = 10**22; - uint256 depositAmount = 5 * (10**18); + uint256 mintAmount = 10 ** 22; + uint256 depositAmount = 5 * (10 ** 18); uint32 fillDeadlineBuffer = 7200; function setUp() public { diff --git a/test/evm/foundry/local/SpokePool_EIP7702.t.sol b/test/evm/foundry/local/SpokePool_EIP7702.t.sol index 58f9907e0..6d8d5c37d 100644 --- a/test/evm/foundry/local/SpokePool_EIP7702.t.sol +++ b/test/evm/foundry/local/SpokePool_EIP7702.t.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; import { Test } from "forge-std/Test.sol"; import { MockSpokePool } from "../../../../contracts/test/MockSpokePool.sol"; import { WETH9 } from "../../../../contracts/external/WETH9.sol"; -import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import { ERC1967Proxy } from "@openzeppelin/contracts-v4/proxy/ERC1967/ERC1967Proxy.sol"; import { AddressToBytes32, Bytes32ToAddress } from "../../../../contracts/libraries/AddressConverters.sol"; import { V3SpokePoolInterface } from "../../../../contracts/interfaces/V3SpokePoolInterface.sol"; diff --git a/test/evm/foundry/local/Universal_Adapter.t.sol b/test/evm/foundry/local/Universal_Adapter.t.sol index db5f09b16..60dabd9bd 100644 --- a/test/evm/foundry/local/Universal_Adapter.t.sol +++ b/test/evm/foundry/local/Universal_Adapter.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; import { Test } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import { ERC20 } from "@openzeppelin/contracts-v4/token/ERC20/ERC20.sol"; import { Universal_Adapter, HubPoolStore } from "../../../../contracts/chain-adapters/Universal_Adapter.sol"; import { MockHubPool } from "../../../../contracts/test/MockHubPool.sol"; import { HubPoolInterface } from "../../../../contracts/interfaces/HubPoolInterface.sol"; diff --git a/test/evm/foundry/local/Universal_SpokePool.t.sol b/test/evm/foundry/local/Universal_SpokePool.t.sol index eaca37105..8edb25c67 100644 --- a/test/evm/foundry/local/Universal_SpokePool.t.sol +++ b/test/evm/foundry/local/Universal_SpokePool.t.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.0; import { Test } from "forge-std/Test.sol"; -import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import { ERC20 } from "@openzeppelin/contracts-v4/token/ERC20/ERC20.sol"; +import { ERC1967Proxy } from "@openzeppelin/contracts-v4/proxy/ERC1967/ERC1967Proxy.sol"; import { Universal_SpokePool, IHelios } from "../../../../contracts/Universal_SpokePool.sol"; import "../../../../contracts/SpokePool.sol"; diff --git a/test/evm/foundry/local/WithdrawalHelper.t.sol b/test/evm/foundry/local/WithdrawalHelper.t.sol index b6bdac8cc..162906e41 100644 --- a/test/evm/foundry/local/WithdrawalHelper.t.sol +++ b/test/evm/foundry/local/WithdrawalHelper.t.sol @@ -2,9 +2,9 @@ pragma solidity ^0.8.0; import { Test } from "forge-std/Test.sol"; -import { ERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -import { UUPSUpgradeable } from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; +import { ERC20, IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/ERC20.sol"; +import { ERC1967Proxy } from "@openzeppelin/contracts-v4/proxy/ERC1967/ERC1967Proxy.sol"; +import { UUPSUpgradeable } from "@openzeppelin/contracts-v4/proxy/utils/UUPSUpgradeable.sol"; import { Lib_PredeployAddresses } from "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol"; import { ITokenMessenger } from "../../../../contracts/external/interfaces/CCTPInterfaces.sol"; import { Arbitrum_WithdrawalHelper } from "../../../../contracts/chain-adapters/l2/Arbitrum_WithdrawalHelper.sol"; diff --git a/test/evm/foundry/local/ZkStack_Adapter.t.sol b/test/evm/foundry/local/ZkStack_Adapter.t.sol index a0b89753a..504c5a41d 100644 --- a/test/evm/foundry/local/ZkStack_Adapter.t.sol +++ b/test/evm/foundry/local/ZkStack_Adapter.t.sol @@ -3,10 +3,10 @@ pragma solidity ^0.8.0; import { Test } from "forge-std/Test.sol"; -import { ERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; +import { ERC20, IERC20 } from "@openzeppelin/contracts-v4/token/ERC20/ERC20.sol"; +import { IERC20Upgradeable } from "@openzeppelin/contracts-upgradeable-v4/token/ERC20/IERC20Upgradeable.sol"; import { IL1StandardBridge } from "@eth-optimism/contracts/L1/messaging/IL1StandardBridge.sol"; -import { FinderInterface } from "@uma/core/contracts/data-verification-mechanism/interfaces/FinderInterface.sol"; +import { FinderInterface } from "../../../../contracts/external/uma/core/contracts/data-verification-mechanism/interfaces/FinderInterface.sol"; import { ZkStack_Adapter } from "../../../../contracts/chain-adapters/ZkStack_Adapter.sol"; import { ZkStack_CustomGasToken_Adapter, FunderInterface } from "../../../../contracts/chain-adapters/ZkStack_CustomGasToken_Adapter.sol"; diff --git a/yarn.lock b/yarn.lock index 5c5974a4f..f08f387af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2552,11 +2552,26 @@ dependencies: "@opentelemetry/core" "^1.1.0" -"@openzeppelin/contracts-upgradeable@4.9.6", "@openzeppelin/contracts-upgradeable@^4.8.1": +"@openzeppelin/contracts-upgradeable-v4@npm:@openzeppelin/contracts-upgradeable@4.9.6": version "4.9.6" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.6.tgz#38b21708a719da647de4bb0e4802ee235a0d24df" integrity sha512-m4iHazOsOCv1DgM7eD7GupTJ+NFVujRZt1wzddDPSVGpWdKq1SKkla5htKG7+IS4d2XOCtzkUNwRZ7Vq5aEUMA== +"@openzeppelin/contracts-upgradeable@5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.5.0.tgz#e35b3ededa5ccc13205c2b42e2058cd5cb7d424a" + integrity sha512-Va5hKG5oaK0EE5bXTVWugcGimMHazxL+SL523dH6WVbGiuLXwuWr9oxtLyPHQSVGtgmlIgtKNR5V+OUpCIUwFQ== + +"@openzeppelin/contracts-upgradeable@^4.8.1": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.6.tgz#38b21708a719da647de4bb0e4802ee235a0d24df" + integrity sha512-m4iHazOsOCv1DgM7eD7GupTJ+NFVujRZt1wzddDPSVGpWdKq1SKkla5htKG7+IS4d2XOCtzkUNwRZ7Vq5aEUMA== + +"@openzeppelin/contracts-v4@npm:@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/contracts@3.4.1-solc-0.7-2": version "3.4.1-solc-0.7-2" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.1-solc-0.7-2.tgz#371c67ebffe50f551c3146a9eec5fe6ffe862e92" @@ -2572,7 +2587,12 @@ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.4.2.tgz#4e889c9c66e736f7de189a53f8ba5b8d789425c2" integrity sha512-NyJV7sJgoGYqbtNUWgzzOGW4T6rR19FmX1IJgXGdapGPWsuMelGJn9h03nos0iqfforCbCB0iYIR0MtIuIFLLw== -"@openzeppelin/contracts@4.9.6", "@openzeppelin/contracts@^4.2.0", "@openzeppelin/contracts@^4.8.1": +"@openzeppelin/contracts@5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-5.5.0.tgz#24e8a2f9598de484dcb223512af656edf52bc0e8" + integrity sha512-R8hq4zmKKWP2c7OxeRgAcjZwvF5W0Qq2OIX7degrtdM52Q9xYr4MLJdUAVPKGUewNJ1qo+M6YiZLLnNUnjP/gg== + +"@openzeppelin/contracts@^4.2.0", "@openzeppelin/contracts@^4.8.1": version "4.9.6" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.6.tgz#2a880a24eb19b4f8b25adc2a5095f2aa27f39677" integrity sha512-xSmezSupL+y9VkHZJGDoCBpmnB2ogM13ccaYDWqJTfS3dbuHkgjuwDFUmaFauBCboQMGB/S5UqUl2y54X99BmA== @@ -4510,22 +4530,6 @@ "@uniswap/v3-core" "^1.0.0-rc.2" "@uniswap/v3-periphery" "^1.0.0-beta.23" -"@uma/core@^2.61.0": - version "2.61.0" - resolved "https://registry.yarnpkg.com/@uma/core/-/core-2.61.0.tgz#29580736349a47af8fb10beb4bb3b50bfcf912f5" - integrity sha512-bnk+CWW+uWpRilrgUny/gDXHKomG+h1Ug84OXdx+AAvj1/BtlMDOCNNt1OX8LSAz+a0hkiN9s24/zgHclTC/sg== - dependencies: - "@gnosis.pm/safe-contracts" "^1.3.0" - "@gnosis.pm/zodiac" "3.2.0" - "@maticnetwork/fx-portal" "^1.0.4" - "@openzeppelin/contracts" "4.9.6" - "@uma/common" "^2.37.3" - "@uniswap/lib" "4.0.1-alpha" - "@uniswap/v2-core" "1.0.0" - "@uniswap/v2-periphery" "1.1.0-beta.0" - "@uniswap/v3-core" "^1.0.0-rc.2" - "@uniswap/v3-periphery" "^1.0.0-beta.23" - "@uma/merkle-distributor@^1.3.38": version "1.3.40" resolved "https://registry.yarnpkg.com/@uma/merkle-distributor/-/merkle-distributor-1.3.40.tgz#70ba0ebf0fe923851786396bcb9a59a5a931127b"