Skip to content

Commit

Permalink
feat(cher): deploy cher contracts (#856)
Browse files Browse the repository at this point in the history
  • Loading branch information
amateima authored Jan 13, 2025
1 parent e03e0b6 commit d4c41a9
Show file tree
Hide file tree
Showing 15 changed files with 4,380 additions and 7 deletions.
72 changes: 72 additions & 0 deletions contracts/Cher_SpokePool.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import "@eth-optimism/contracts/libraries/constants/Lib_PredeployAddresses.sol";

import "./Ovm_SpokePool.sol";
import "./external/interfaces/CCTPInterfaces.sol";
import { IOpUSDCBridgeAdapter } from "./external/interfaces/IOpUSDCBridgeAdapter.sol";

/**
* @notice Cher SpokePool.
* @custom:security-contact [email protected]
*/
contract Cher_SpokePool is Ovm_SpokePool {
using SafeERC20 for IERC20;

// Address of the custom L2 USDC bridge.
address private constant USDC_BRIDGE = 0x8be79275FCfD08A931087ECf70Ba8a99aee3AC59;

/// @custom:oz-upgrades-unsafe-allow constructor
constructor(
address _wrappedNativeTokenAddress,
uint32 _depositQuoteTimeBuffer,
uint32 _fillDeadlineBuffer,
IERC20 _l2Usdc,
ITokenMessenger _cctpTokenMessenger
)
Ovm_SpokePool(
_wrappedNativeTokenAddress,
_depositQuoteTimeBuffer,
_fillDeadlineBuffer,
_l2Usdc,
_cctpTokenMessenger
)
{} // solhint-disable-line no-empty-blocks

/**
* @notice Construct the OVM Cher 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.
* @param _withdrawalRecipient Address which receives token withdrawals. Can be changed by admin. For Spoke Pools on L2, this will
*/
function initialize(
uint32 _initialDepositId,
address _crossDomainAdmin,
address _withdrawalRecipient
) public initializer {
__OvmSpokePool_init(_initialDepositId, _crossDomainAdmin, _withdrawalRecipient, Lib_PredeployAddresses.OVM_ETH);
}

/**
* @notice Cher-specific logic to bridge tokens back to the hub pool contract on L1.
* @param amountToReturn Amount of the token to bridge back.
* @param l2TokenAddress Address of the l2 Token to bridge back. This token will either be bridged back to the token defined in the mapping `remoteL1Tokens`,
* or via the canonical mapping defined in the bridge contract retrieved from `tokenBridges`.
* @dev This implementation deviates slightly from `_bridgeTokensToHubPool` in the `Ovm_SpokePool` contract since
* this chain uses Circle's bridged (upgradable to native) USDC standard, which uses a custom interface.
*/
function _bridgeTokensToHubPool(uint256 amountToReturn, address l2TokenAddress) internal virtual override {
// Handle custom USDC bridge which doesn't conform to the standard bridge interface. In the future, CCTP may be used to bridge USDC to mainnet, in which
// case bridging logic is handled by the Ovm_SpokePool code. In the meantime, if CCTP is not enabled, then use the USDC bridge. Once CCTP is activated on
// Cher, this block of code will be unused.
if (l2TokenAddress == address(usdcToken) && !_isCCTPEnabled()) {
usdcToken.safeIncreaseAllowance(USDC_BRIDGE, amountToReturn);
IOpUSDCBridgeAdapter(USDC_BRIDGE).sendMessage(
withdrawalRecipient, // _to. Withdraw, over the bridge, to the l1 hub pool contract.
amountToReturn, // _amount.
l1Gas // _minGasLimit. Same value used in other OpStack bridges.
);
} else super._bridgeTokensToHubPool(amountToReturn, l2TokenAddress);
}
}
31 changes: 31 additions & 0 deletions deploy/060_deploy_cher_spokepool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { DeployFunction } from "hardhat-deploy/types";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { deployNewProxy, getSpokePoolDeploymentInfo } from "../utils/utils.hre";
import { FILL_DEADLINE_BUFFER, WETH, QUOTE_TIME_BUFFER, ZERO_ADDRESS, USDCe } from "./consts";

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { hubPool, spokeChainId } = await getSpokePoolDeploymentInfo(hre);

const initArgs = [
1,
// Set hub pool as cross domain admin since it delegatecalls the Adapter logic.
hubPool.address,
hubPool.address,
];
const constructorArgs = [
WETH[spokeChainId],
QUOTE_TIME_BUFFER,
FILL_DEADLINE_BUFFER,
// Cher's bridged USDC is upgradeable to native. There are not two different
// addresses for bridges/native USDC. This address is also used in the spoke pool
// to determine whether to use CCTP (in the future) or the custom USDC bridge.
USDCe[spokeChainId],
// L2_ADDRESS_MAP[spokeChainId].cctpTokenMessenger,
// For now, we are not using the CCTP bridge and can disable by setting
// the cctpTokenMessenger to the zero address.
ZERO_ADDRESS,
];
await deployNewProxy("Cher_SpokePool", constructorArgs, initArgs);
};
module.exports = func;
func.tags = ["CherSpokePool", "cher"];
5 changes: 5 additions & 0 deletions deploy/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ export const OP_STACK_ADDRESS_MAP: {
L1StandardBridge: "0x88ff1e5b602916615391f55854588efcbb7663f0",
L1OpUSDCBridgeAdapter: ZERO_ADDRESS,
},
[CHAIN_IDs.CHER]: {
L1CrossDomainMessenger: "0x9cf951e3f74b644e621b36ca9cea147a78d4c39f",
L1StandardBridge: "0xeb9bf100225c214efc3e7c651ebbadcf85177607",
L1OpUSDCBridgeAdapter: "0xC67A8c5f22b40274Ca7C4A56Db89569Ee2AD3FAb",
},
[CHAIN_IDs.LISK]: {
L1CrossDomainMessenger: "0x31B72D76FB666844C41EdF08dF0254875Dbb7edB",
L1StandardBridge: "0x2658723Bf70c7667De6B25F99fcce13A16D25d08",
Expand Down
8 changes: 8 additions & 0 deletions deployments/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ This is because this `deployments.json` file is used by bots in [`@across-protoc
| AcrossConfigStore | [0x3B03509645713718B78951126E0A6de6f10043f5](https://etherscan.io/address/0x3B03509645713718B78951126E0A6de6f10043f5) |
| Across Bond Token | [0xee1dc6bcf1ee967a350e9ac6caaaa236109002ea](https://etherscan.io/address/0xee1dc6bcf1ee967a350e9ac6caaaa236109002ea) |
| MulticallHandler | [0x924a9f036260DdD5808007E1AA95f08eD08aA569](https://etherscan.io/address/0x924a9f036260DdD5808007E1AA95f08eD08aA569) |
| Cher Adapter | [0x0c9d064523177dBB55CFE52b9D0c485FBFc35FD2](https://etherscan.io/address/0x0c9d064523177dBB55CFE52b9D0c485FBFc35FD2) |

## Optimism mainnet (10)

Expand Down Expand Up @@ -137,3 +138,10 @@ This is because this `deployments.json` file is used by bots in [`@across-protoc
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Ink_SpokePool | [0xeF684C38F94F48775959ECf2012D7E864ffb9dd4](https://explorer.inkonchain.com/address/0xeF684C38F94F48775959ECf2012D7E864ffb9dd4) |
| MulticallHandler | [0x924a9f036260DdD5808007E1AA95f08eD08aA569](https://explorer.inkonchain.com/address/0x924a9f036260DdD5808007E1AA95f08eD08aA569) |

## Cher mainnet (1868)

| Contract Name | Address |
| ---------------- | --------------------------------------------------------------------------------------------------------------------- |
| Cher_SpokePool | [0x3baD7AD0728f9917d1Bf08af5782dCbD516cDd96](https://etherscan.io/address/0x3baD7AD0728f9917d1Bf08af5782dCbD516cDd96) |
| MulticallHandler | [0x924a9f036260DdD5808007E1AA95f08eD08aA569](https://etherscan.io/address/0x924a9f036260DdD5808007E1AA95f08eD08aA569) |
1 change: 1 addition & 0 deletions deployments/cher/.chainId
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1868
Loading

0 comments on commit d4c41a9

Please sign in to comment.