From f48a8faa38959112ba9b680ad70affa89fdb423d Mon Sep 17 00:00:00 2001 From: benk10 Date: Thu, 11 Jul 2024 11:28:59 -0500 Subject: [PATCH] Integrate token with arbitrum bridge --- contracts/HatTokenArbitrumBridgeL1.sol | 38 -------- contracts/HatTokenArbitrumBridgeL2.sol | 7 -- contracts/{ => token}/HATToken.sol | 2 +- contracts/token/HatTokenArbitrumBridgeL1.sol | 93 ++++++++++++++++++++ contracts/token/HatTokenArbitrumBridgeL2.sol | 36 ++++++++ 5 files changed, 130 insertions(+), 46 deletions(-) delete mode 100644 contracts/HatTokenArbitrumBridgeL1.sol delete mode 100644 contracts/HatTokenArbitrumBridgeL2.sol rename contracts/{ => token}/HATToken.sol (98%) create mode 100644 contracts/token/HatTokenArbitrumBridgeL1.sol create mode 100644 contracts/token/HatTokenArbitrumBridgeL2.sol diff --git a/contracts/HatTokenArbitrumBridgeL1.sol b/contracts/HatTokenArbitrumBridgeL1.sol deleted file mode 100644 index e3b6f23d..00000000 --- a/contracts/HatTokenArbitrumBridgeL1.sol +++ /dev/null @@ -1,38 +0,0 @@ - -import "./HATToken.sol"; -import "@arbitrum/token-bridge-contracts/contracts/tokenbridge/ethereum/ICustomToken.sol"; - -contract HATTokenArbitrumBridgeL1 is ICustomToken, HATToken { - /** functions for registring the token with the arbitrum bridge */ - function isArbitrumEnabled() external view override returns (uint8) { - return uint8(0xb1); - } - - function registerTokenOnL2( - address l2CustomTokenAddress, - uint256 maxSubmissionCostForCustomGateway, - uint256 maxSubmissionCostForRouter, - uint256 maxGasForCustomGateway, - uint256 maxGasForRouter, - uint256 gasPriceBid, - uint256 valueForGateway, - uint256 valueForRouter, - address creditBackAddress - ) public payable virtual override { - IL1CustomGateway(gateway).registerTokenToL2{ value: valueForGateway }( - l2CustomTokenAddress, - maxGasForCustomGateway, - gasPriceBid, - maxSubmissionCostForCustomGateway, - creditBackAddress - ); - - IGatewayRouter2(router).setGateway{ value: valueForRouter }( - gateway, - maxGasForRouter, - gasPriceBid, - maxSubmissionCostForRouter, - creditBackAddress - ); - } -} \ No newline at end of file diff --git a/contracts/HatTokenArbitrumBridgeL2.sol b/contracts/HatTokenArbitrumBridgeL2.sol deleted file mode 100644 index 3ef0dc4e..00000000 --- a/contracts/HatTokenArbitrumBridgeL2.sol +++ /dev/null @@ -1,7 +0,0 @@ - -import "./HATToken.sol"; -import "@arbitrum/token-bridge-contracts/contracts/tokenbridge/arbitrum/IArbToken.sol"; - -contract HATTokenArbitrumBridgeL2 is IArbToken, HATToken { - /** functions for registring the token with the arbitrum bridge */ -} \ No newline at end of file diff --git a/contracts/HATToken.sol b/contracts/token/HATToken.sol similarity index 98% rename from contracts/HATToken.sol rename to contracts/token/HATToken.sol index 580a48a0..953f8bbe 100644 --- a/contracts/HATToken.sol +++ b/contracts/token/HATToken.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.16; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Capped.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; -import "./interfaces/IHATToken.sol"; +import "../interfaces/IHATToken.sol"; contract HATToken is IHATToken, ERC20Votes, ERC20Capped, Ownable { diff --git a/contracts/token/HatTokenArbitrumBridgeL1.sol b/contracts/token/HatTokenArbitrumBridgeL1.sol new file mode 100644 index 00000000..51e31093 --- /dev/null +++ b/contracts/token/HatTokenArbitrumBridgeL1.sol @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +import "./HATToken.sol"; +import "@arbitrum/token-bridge-contracts/contracts/tokenbridge/ethereum/ICustomToken.sol"; + +/** + * @title Interface needed to call function registerTokenToL2 of the L1CustomGateway + */ +interface IL1CustomGateway { + function registerTokenToL2( + address _l2Address, + uint256 _maxGas, + uint256 _gasPriceBid, + uint256 _maxSubmissionCost, + address _creditBackAddress + ) external payable returns (uint256); +} + +/** + * @title Interface needed to call function setGateway of the L2GatewayRouter + */ +interface IL2GatewayRouter { + function setGateway( + address _gateway, + uint256 _maxGas, + uint256 _gasPriceBid, + uint256 _maxSubmissionCost, + address _creditBackAddress + ) external payable returns (uint256); +} + +contract HATTokenArbitrumBridgeL1 is ICustomToken, HATToken { + address private customGatewayAddress; + address private routerAddress; + bool private shouldRegisterGateway; + + constructor (address _customGatewayAddress, address _routerAddress, address _governance) HATToken(_governance) { + customGatewayAddress = _customGatewayAddress; + routerAddress = _routerAddress; + } + + function isArbitrumEnabled() external view override returns (uint8) { + require(shouldRegisterGateway, "NOT_EXPECTED_CALL"); + return uint8(0xb1); + } + + function registerTokenOnL2( + address l2CustomTokenAddress, + uint256 maxSubmissionCostForCustomGateway, + uint256 maxSubmissionCostForRouter, + uint256 maxGasForCustomGateway, + uint256 maxGasForRouter, + uint256 gasPriceBid, + uint256 valueForGateway, + uint256 valueForRouter, + address creditBackAddress + ) public override payable onlyOwner { + // we temporarily set `shouldRegisterGateway` to true for the callback in registerTokenToL2 to succeed + bool prev = shouldRegisterGateway; + shouldRegisterGateway = true; + + IL1CustomGateway(customGatewayAddress).registerTokenToL2{ value: valueForGateway }( + l2CustomTokenAddress, + maxGasForCustomGateway, + gasPriceBid, + maxSubmissionCostForCustomGateway, + creditBackAddress + ); + + IL2GatewayRouter(routerAddress).setGateway{ value: valueForRouter }( + customGatewayAddress, + maxGasForRouter, + gasPriceBid, + maxSubmissionCostForRouter, + creditBackAddress + ); + + shouldRegisterGateway = prev; + } + + function transferFrom( + address sender, + address recipient, + uint256 amount + ) public override(ICustomToken, ERC20) returns (bool) { + return super.transferFrom(sender, recipient, amount); + } + + function balanceOf(address account) public view override(ICustomToken, ERC20) returns (uint256) { + return super.balanceOf(account); + } +} \ No newline at end of file diff --git a/contracts/token/HatTokenArbitrumBridgeL2.sol b/contracts/token/HatTokenArbitrumBridgeL2.sol new file mode 100644 index 00000000..cce5d438 --- /dev/null +++ b/contracts/token/HatTokenArbitrumBridgeL2.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.16; + +import "./HATToken.sol"; +import "@arbitrum/token-bridge-contracts/contracts/tokenbridge/arbitrum/IArbToken.sol"; + +contract HATTokenArbitrumBridgeL2 is HATToken, IArbToken { + address public l2Gateway; + address public override l1Address; + + modifier onlyL2Gateway() { + require(msg.sender == l2Gateway, "NOT_GATEWAY"); + _; + } + + constructor(address _l2Gateway, address _l1TokenAddress) HATToken(address(0)) { + l2Gateway = _l2Gateway; + l1Address = _l1TokenAddress; + transferable = true; + emit TransferableSet(); + } + + /** + * @notice should increase token supply by amount, and should only be callable by the L2Gateway. + */ + function bridgeMint(address account, uint256 amount) external override onlyL2Gateway { + _mint(account, amount); + } + + /** + * @notice should decrease token supply by amount, and should only be callable by the L2Gateway. + */ + function bridgeBurn(address account, uint256 amount) external override onlyL2Gateway { + _burn(account, amount); + } +} \ No newline at end of file