diff --git a/contracts/DoctorWho_SpokePool.sol b/contracts/Unichain_SpokePool.sol similarity index 91% rename from contracts/DoctorWho_SpokePool.sol rename to contracts/Unichain_SpokePool.sol index 6744ffb9e..3e349c49f 100644 --- a/contracts/DoctorWho_SpokePool.sol +++ b/contracts/Unichain_SpokePool.sol @@ -6,10 +6,10 @@ import "./Ovm_SpokePool.sol"; import "./external/interfaces/CCTPInterfaces.sol"; /** - * @notice DoctorWho Spoke pool. + * @notice Unichain Spoke pool. * @custom:security-contact bugs@across.to */ -contract DoctorWho_SpokePool is Ovm_SpokePool { +contract Unichain_SpokePool is Ovm_SpokePool { /// @custom:oz-upgrades-unsafe-allow constructor constructor( address _wrappedNativeTokenAddress, @@ -28,7 +28,7 @@ contract DoctorWho_SpokePool is Ovm_SpokePool { {} // solhint-disable-line no-empty-blocks /** - * @notice Construct the OVM DoctorWho SpokePool. + * @notice Construct the OVM Unichain SpokePool. * @param _initialDepositId Starting deposit ID. Set to 0 unless this is a re-deployment in order to mitigate * relay hash collisions. * @param _crossDomainAdmin Cross domain admin to set. Can be changed by admin. diff --git a/contracts/chain-adapters/DoctorWho_Adapter.sol b/contracts/chain-adapters/Unichain_Adapter.sol similarity index 91% rename from contracts/chain-adapters/DoctorWho_Adapter.sol rename to contracts/chain-adapters/Unichain_Adapter.sol index 75af3aa41..7b7e8f5ad 100644 --- a/contracts/chain-adapters/DoctorWho_Adapter.sol +++ b/contracts/chain-adapters/Unichain_Adapter.sol @@ -16,7 +16,7 @@ import "../libraries/CircleCCTPAdapter.sol"; import "../external/interfaces/CCTPInterfaces.sol"; /** - * @notice Contract containing logic to send messages from L1 to Doctor Who. This is a modified version of the Optimism adapter + * @notice Contract containing logic to send messages from L1 to Unichain. This is a modified version of the Optimism adapter * that excludes the custom bridging logic. * @custom:security-contact bugs@across.to * @dev Public functions calling external contracts do not guard against reentrancy because they are expected to be @@ -26,7 +26,7 @@ import "../external/interfaces/CCTPInterfaces.sol"; */ // solhint-disable-next-line contract-name-camelcase -contract DoctorWho_Adapter is CrossDomainEnabled, AdapterInterface, CircleCCTPAdapter { +contract Unichain_Adapter is CrossDomainEnabled, AdapterInterface, CircleCCTPAdapter { using SafeERC20 for IERC20; uint32 public constant L2_GAS_LIMIT = 200_000; @@ -50,15 +50,15 @@ contract DoctorWho_Adapter is CrossDomainEnabled, AdapterInterface, CircleCCTPAd ITokenMessenger _cctpTokenMessenger ) CrossDomainEnabled(_crossDomainMessenger) - CircleCCTPAdapter(_l1Usdc, _cctpTokenMessenger, CircleDomainIds.DoctorWho) + CircleCCTPAdapter(_l1Usdc, _cctpTokenMessenger, CircleDomainIds.Unichain) { L1_WETH = _l1Weth; L1_STANDARD_BRIDGE = _l1StandardBridge; } /** - * @notice Send cross-chain message to target on Doctor Who. - * @param target Contract on Doctor Who that will receive message. + * @notice Send cross-chain message to target on Unichain. + * @param target Contract on Unichain that will receive message. * @param message Data to send to target. */ function relayMessage(address target, bytes calldata message) external payable override { @@ -67,7 +67,7 @@ contract DoctorWho_Adapter is CrossDomainEnabled, AdapterInterface, CircleCCTPAd } /** - * @notice Bridge tokens to Doctor Who. + * @notice Bridge tokens to Unichain. * @param l1Token L1 token to deposit. * @param l2Token L2 token to receive. * @param amount Amount of L1 tokens to deposit and L2 tokens to receive. diff --git a/contracts/libraries/CircleCCTPAdapter.sol b/contracts/libraries/CircleCCTPAdapter.sol index 9db21c94b..fdc2c8046 100644 --- a/contracts/libraries/CircleCCTPAdapter.sol +++ b/contracts/libraries/CircleCCTPAdapter.sol @@ -13,7 +13,7 @@ library CircleDomainIds { uint32 public constant Solana = 5; uint32 public constant Base = 6; uint32 public constant Polygon = 7; - uint32 public constant DoctorWho = 10; + uint32 public constant Unichain = 10; // Use this value for placeholder purposes only for adapters that extend this adapter but haven't yet been // assigned a domain ID by Circle. uint32 public constant UNINITIALIZED = type(uint32).max; diff --git a/deploy/061_deploy_unichain_adapter.ts b/deploy/061_deploy_unichain_adapter.ts index 1a2f53113..d95c7359c 100644 --- a/deploy/061_deploy_unichain_adapter.ts +++ b/deploy/061_deploy_unichain_adapter.ts @@ -23,7 +23,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { L1_ADDRESS_MAP[chainId].cctpTokenMessenger, ]; - const instance = await hre.deployments.deploy("DoctorWho_Adapter", { + const instance = await hre.deployments.deploy("Unichain_Adapter", { from: deployer, log: true, skipIfAlreadyDeployed: false, @@ -33,4 +33,4 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { }; module.exports = func; -func.tags = ["DoctorWhoAdapter", "doctorwho"]; +func.tags = ["UnichainAdapter", "unichain"]; diff --git a/deploy/062_deploy_unichain_spokepool.ts b/deploy/062_deploy_unichain_spokepool.ts index 2fe709277..cc854abfd 100644 --- a/deploy/062_deploy_unichain_spokepool.ts +++ b/deploy/062_deploy_unichain_spokepool.ts @@ -19,7 +19,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { USDC[spokeChainId], L2_ADDRESS_MAP[spokeChainId].cctpTokenMessenger, ]; - await deployNewProxy("DoctorWho_SpokePool", constructorArgs, initArgs); + await deployNewProxy("Unichain_SpokePool", constructorArgs, initArgs); }; module.exports = func; -func.tags = ["DoctorWhoSpokePool", "doctorwho"]; +func.tags = ["UnichainSpokePool", "unichain"]; diff --git a/deployments/README.md b/deployments/README.md index 8742d5b34..f56428443 100644 --- a/deployments/README.md +++ b/deployments/README.md @@ -32,6 +32,7 @@ This is because this `deployments.json` file is used by bots in [`@across-protoc | Across Bond Token | [0xee1dc6bcf1ee967a350e9ac6caaaa236109002ea](https://etherscan.io/address/0xee1dc6bcf1ee967a350e9ac6caaaa236109002ea) | | MulticallHandler | [0x924a9f036260DdD5808007E1AA95f08eD08aA569](https://etherscan.io/address/0x924a9f036260DdD5808007E1AA95f08eD08aA569) | | Cher Adapter | [0x0c9d064523177dBB55CFE52b9D0c485FBFc35FD2](https://etherscan.io/address/0x0c9d064523177dBB55CFE52b9D0c485FBFc35FD2) | +| Unichain Adapter | [0xFADcC43096756e1527306FD92982FEbBe3c629Fa](https://etherscan.io/address/0xFADcC43096756e1527306FD92982FEbBe3c629Fa) | ## Optimism mainnet (10) diff --git a/deployments/deployments.json b/deployments/deployments.json index aa2595431..c178834b0 100644 --- a/deployments/deployments.json +++ b/deployments/deployments.json @@ -31,7 +31,7 @@ "AlephZero_Adapter": { "address": "0x6F4083304C2cA99B077ACE06a5DcF670615915Af", "blockNumber": 21131132 }, "Ink_Adapter": { "address": "0x7e90a40c7519b041a7df6498fbf5662e8cfc61d2", "blockNumber": 21438590 }, "Cher_Adapter": { "address": "0x0c9d064523177dBB55CFE52b9D0c485FBFc35FD2", "blockNumber": 21597341 }, - "DoctorWho_Adapter": { "address": "0xFADcC43096756e1527306FD92982FEbBe3c629Fa", "blockNumber": 21773451 } + "Unichain_Adapter": { "address": "0xFADcC43096756e1527306FD92982FEbBe3c629Fa", "blockNumber": 21773451 } }, "10": { "SpokePool": { "address": "0x6f26Bf09B1C792e3228e5467807a900A503c0281", "blockNumber": 93903076 }, diff --git a/deployments/doctorwho/.chainId b/deployments/unichain/.chainId similarity index 100% rename from deployments/doctorwho/.chainId rename to deployments/unichain/.chainId diff --git a/deployments/doctorwho/Multicallhandler.json b/deployments/unichain/Multicallhandler.json similarity index 100% rename from deployments/doctorwho/Multicallhandler.json rename to deployments/unichain/Multicallhandler.json diff --git a/deployments/doctorwho/DoctorWho_SpokePool.json b/deployments/unichain/Unichain_SpokePool.json similarity index 100% rename from deployments/doctorwho/DoctorWho_SpokePool.json rename to deployments/unichain/Unichain_SpokePool.json diff --git a/deployments/doctorwho/solcInputs/1c069ec29fe635ad20f5c251cc99e014.json b/deployments/unichain/solcInputs/1c069ec29fe635ad20f5c251cc99e014.json similarity index 99% rename from deployments/doctorwho/solcInputs/1c069ec29fe635ad20f5c251cc99e014.json rename to deployments/unichain/solcInputs/1c069ec29fe635ad20f5c251cc99e014.json index 932d43f75..9f1e7e785 100644 --- a/deployments/doctorwho/solcInputs/1c069ec29fe635ad20f5c251cc99e014.json +++ b/deployments/unichain/solcInputs/1c069ec29fe635ad20f5c251cc99e014.json @@ -95,7 +95,7 @@ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" }, "contracts/DoctorWho_SpokePool.sol": { - "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\nimport \"@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol\";\n\nimport \"./Ovm_SpokePool.sol\";\nimport \"./external/interfaces/CCTPInterfaces.sol\";\n\n/**\n * @notice DoctorWho Spoke pool.\n * @custom:security-contact bugs@across.to\n */\ncontract DoctorWho_SpokePool is Ovm_SpokePool {\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor(\n address _wrappedNativeTokenAddress,\n uint32 _depositQuoteTimeBuffer,\n uint32 _fillDeadlineBuffer,\n IERC20 _l2Usdc,\n ITokenMessenger _cctpTokenMessenger\n )\n Ovm_SpokePool(\n _wrappedNativeTokenAddress,\n _depositQuoteTimeBuffer,\n _fillDeadlineBuffer,\n _l2Usdc,\n _cctpTokenMessenger\n )\n {} // solhint-disable-line no-empty-blocks\n\n /**\n * @notice Construct the OVM DoctorWho SpokePool.\n * @param _initialDepositId Starting deposit ID. Set to 0 unless this is a re-deployment in order to mitigate\n * relay hash collisions.\n * @param _crossDomainAdmin Cross domain admin to set. Can be changed by admin.\n * @param _withdrawalRecipient Address which receives token withdrawals. Can be changed by admin. For Spoke Pools on L2, this will\n * likely be the hub pool.\n */\n function initialize(\n uint32 _initialDepositId,\n address _crossDomainAdmin,\n address _withdrawalRecipient\n ) public initializer {\n __OvmSpokePool_init(_initialDepositId, _crossDomainAdmin, _withdrawalRecipient, Lib_PredeployAddresses.OVM_ETH);\n }\n}\n" + "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0;\nimport \"@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol\";\n\nimport \"./Ovm_SpokePool.sol\";\nimport \"./external/interfaces/CCTPInterfaces.sol\";\n\n/**\n * @notice Unichain Spoke pool.\n * @custom:security-contact bugs@across.to\n */\ncontract DoctorWho_SpokePool is Ovm_SpokePool {\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor(\n address _wrappedNativeTokenAddress,\n uint32 _depositQuoteTimeBuffer,\n uint32 _fillDeadlineBuffer,\n IERC20 _l2Usdc,\n ITokenMessenger _cctpTokenMessenger\n )\n Ovm_SpokePool(\n _wrappedNativeTokenAddress,\n _depositQuoteTimeBuffer,\n _fillDeadlineBuffer,\n _l2Usdc,\n _cctpTokenMessenger\n )\n {} // solhint-disable-line no-empty-blocks\n\n /**\n * @notice Construct the OVM Unichain SpokePool.\n * @param _initialDepositId Starting deposit ID. Set to 0 unless this is a re-deployment in order to mitigate\n * relay hash collisions.\n * @param _crossDomainAdmin Cross domain admin to set. Can be changed by admin.\n * @param _withdrawalRecipient Address which receives token withdrawals. Can be changed by admin. For Spoke Pools on L2, this will\n * likely be the hub pool.\n */\n function initialize(\n uint32 _initialDepositId,\n address _crossDomainAdmin,\n address _withdrawalRecipient\n ) public initializer {\n __OvmSpokePool_init(_initialDepositId, _crossDomainAdmin, _withdrawalRecipient, Lib_PredeployAddresses.OVM_ETH);\n }\n}\n" }, "contracts/erc7683/ERC7683.sol": { "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\n/// @title GaslessCrossChainOrder CrossChainOrder type\n/// @notice Standard order struct to be signed by users, disseminated to fillers, and submitted to origin settler contracts\nstruct GaslessCrossChainOrder {\n /// @dev The contract address that the order is meant to be settled by.\n /// Fillers send this order to this contract address on the origin chain\n address originSettler;\n /// @dev The address of the user who is initiating the swap,\n /// whose input tokens will be taken and escrowed\n address user;\n /// @dev Nonce to be used as replay protection for the order\n uint256 nonce;\n /// @dev The chainId of the origin chain\n uint256 originChainId;\n /// @dev The timestamp by which the order must be opened\n uint32 openDeadline;\n /// @dev The timestamp by which the order must be filled on the destination chain\n uint32 fillDeadline;\n /// @dev Type identifier for the order data. This is an EIP-712 typehash.\n bytes32 orderDataType;\n /// @dev Arbitrary implementation-specific data\n /// Can be used to define tokens, amounts, destination chains, fees, settlement parameters,\n /// or any other order-type specific information\n bytes orderData;\n}\n\n/// @title OnchainCrossChainOrder CrossChainOrder type\n/// @notice Standard order struct for user-opened orders, where the user is the msg.sender.\nstruct OnchainCrossChainOrder {\n /// @dev The timestamp by which the order must be filled on the destination chain\n uint32 fillDeadline;\n /// @dev Type identifier for the order data. This is an EIP-712 typehash.\n bytes32 orderDataType;\n /// @dev Arbitrary implementation-specific data\n /// Can be used to define tokens, amounts, destination chains, fees, settlement parameters,\n /// or any other order-type specific information\n bytes orderData;\n}\n\n/// @title ResolvedCrossChainOrder type\n/// @notice An implementation-generic representation of an order intended for filler consumption\n/// @dev Defines all requirements for filling an order by unbundling the implementation-specific orderData.\n/// @dev Intended to improve integration generalization by allowing fillers to compute the exact input and output information of any order\nstruct ResolvedCrossChainOrder {\n /// @dev The address of the user who is initiating the transfer\n address user;\n /// @dev The chainId of the origin chain\n uint256 originChainId;\n /// @dev The timestamp by which the order must be opened\n uint32 openDeadline;\n /// @dev The timestamp by which the order must be filled on the destination chain(s)\n uint32 fillDeadline;\n /// @dev The unique identifier for this order within this settlement system\n bytes32 orderId;\n /// @dev The max outputs that the filler will send. It's possible the actual amount depends on the state of the destination\n /// chain (destination dutch auction, for instance), so these outputs should be considered a cap on filler liabilities.\n Output[] maxSpent;\n /// @dev The minimum outputs that must to be given to the filler as part of order settlement. Similar to maxSpent, it's possible\n /// that special order types may not be able to guarantee the exact amount at open time, so this should be considered\n /// a floor on filler receipts.\n Output[] minReceived;\n /// @dev Each instruction in this array is parameterizes a single leg of the fill. This provides the filler with the information\n /// necessary to perform the fill on the destination(s).\n FillInstruction[] fillInstructions;\n}\n\n/// @notice Tokens that must be receive for a valid order fulfillment\nstruct Output {\n /// @dev The address of the ERC20 token on the destination chain\n /// @dev address(0) used as a sentinel for the native token\n bytes32 token;\n /// @dev The amount of the token to be sent\n uint256 amount;\n /// @dev The address to receive the output tokens\n bytes32 recipient;\n /// @dev The destination chain for this output\n uint256 chainId;\n}\n\n/// @title FillInstruction type\n/// @notice Instructions to parameterize each leg of the fill\n/// @dev Provides all the origin-generated information required to produce a valid fill leg\nstruct FillInstruction {\n /// @dev The contract address that the order is meant to be settled by\n uint64 destinationChainId;\n /// @dev The contract address that the order is meant to be filled on\n bytes32 destinationSettler;\n /// @dev The data generated on the origin chain needed by the destinationSettler to process the fill\n bytes originData;\n}\n\n/// @title IOriginSettler\n/// @notice Standard interface for settlement contracts on the origin chain\ninterface IOriginSettler {\n /// @notice Signals that an order has been opened\n /// @param orderId a unique order identifier within this settlement system\n /// @param resolvedOrder resolved order that would be returned by resolve if called instead of Open\n event Open(bytes32 indexed orderId, ResolvedCrossChainOrder resolvedOrder);\n\n /// @notice Opens a gasless cross-chain order on behalf of a user.\n /// @dev To be called by the filler.\n /// @dev This method must emit the Open event\n /// @param order The GaslessCrossChainOrder definition\n /// @param signature The user's signature over the order\n /// @param originFillerData Any filler-defined data required by the settler\n function openFor(\n GaslessCrossChainOrder calldata order,\n bytes calldata signature,\n bytes calldata originFillerData\n ) external;\n\n /// @notice Opens a cross-chain order\n /// @dev To be called by the user\n /// @dev This method must emit the Open event\n /// @param order The OnchainCrossChainOrder definition\n function open(OnchainCrossChainOrder calldata order) external;\n\n /// @notice Resolves a specific GaslessCrossChainOrder into a generic ResolvedCrossChainOrder\n /// @dev Intended to improve standardized integration of various order types and settlement contracts\n /// @param order The GaslessCrossChainOrder definition\n /// @param originFillerData Any filler-defined data required by the settler\n /// @return ResolvedCrossChainOrder hydrated order data including the inputs and outputs of the order\n function resolveFor(GaslessCrossChainOrder calldata order, bytes calldata originFillerData)\n external\n view\n returns (ResolvedCrossChainOrder memory);\n\n /// @notice Resolves a specific OnchainCrossChainOrder into a generic ResolvedCrossChainOrder\n /// @dev Intended to improve standardized integration of various order types and settlement contracts\n /// @param order The OnchainCrossChainOrder definition\n /// @return ResolvedCrossChainOrder hydrated order data including the inputs and outputs of the order\n function resolve(OnchainCrossChainOrder calldata order) external view returns (ResolvedCrossChainOrder memory);\n}\n\n/// @title IDestinationSettler\n/// @notice Standard interface for settlement contracts on the destination chain\ninterface IDestinationSettler {\n /// @notice Fills a single leg of a particular order on the destination chain\n /// @param orderId Unique order identifier for this order\n /// @param originData Data emitted on the origin to parameterize the fill\n /// @param fillerData Data provided by the filler to inform the fill or express their preferences\n function fill(\n bytes32 orderId,\n bytes calldata originData,\n bytes calldata fillerData\n ) external;\n}\n"