Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to do single-TX deployment of token bridge for fee token based Orbit chains #37

Merged
merged 35 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
902206e
Set correct templates if fee token is used
gvladika Jul 27, 2023
adf7f4b
Add support for fee token based retryables
gvladika Jul 27, 2023
db4a222
Move fee tokens to inbox to pay for retryables
gvladika Jul 27, 2023
a0029a8
Move getter for canonical L1 router address to L1 creator
gvladika Jul 27, 2023
f399dfa
Init retryable sender from init of L1 creator
gvladika Jul 27, 2023
c6ba878
Adjust script for deploying creator
gvladika Jul 27, 2023
9f0ca76
Fix L1 router address calculation
gvladika Jul 28, 2023
43542bb
Send correct bytecode to L2
gvladika Jul 28, 2023
0e9cc76
Update test script
gvladika Jul 28, 2023
46647a9
Remove unnecessary scripts
gvladika Jul 28, 2023
79bf267
Use existing proxy admin
gvladika Aug 4, 2023
f52ae5b
Merge branch 'erc20-based-bridge' into fee-token-deployer
gvladika Aug 4, 2023
cd35fef
Deploy UpgradeExecutor to L2
gvladika Aug 6, 2023
ab468c1
Refactor upgrade executor flow
gvladika Aug 6, 2023
18ec4b6
Rename env vars
gvladika Aug 6, 2023
6f7ad28
Make verifivier script more complete
gvladika Aug 6, 2023
c4c517d
Fix deployment test
gvladika Aug 7, 2023
38083c7
Use lower case in tests
gvladika Aug 7, 2023
3ca96b2
Don't check weth stuff in case of fee token
gvladika Aug 7, 2023
d5998c2
Use upgrade executor from npm package
gvladika Aug 18, 2023
d6b7ff6
Deploy Multicall on L3
gvladika Aug 19, 2023
30cdd75
Decrease contract size by not hashing the salt prefix
gvladika Aug 19, 2023
eeac040
Prepare crosschain hardhat tests for CI
gvladika Aug 25, 2023
db20781
Merge branch 'erc20-based-bridge' into fee-token-deployer
gvladika Aug 25, 2023
14a2311
Merge branch 'fee-token-deployer' into use-executor
gvladika Aug 25, 2023
864fa61
Update address
gvladika Aug 25, 2023
2d77950
Merge branch 'erc20-based-bridge' into fee-token-deployer
gvladika Aug 31, 2023
1525d26
Merge branch 'fee-token-deployer' into use-executor
gvladika Aug 31, 2023
2ecec9a
Update smart contracts and script to reflect latest rollup ownership …
gvladika Sep 1, 2023
09c9715
Merge pull request #38 from OffchainLabs/use-executor
gvladika Sep 7, 2023
1f2121f
Add docs for computeAddress function
gvladika Sep 7, 2023
6cb2060
Verify retyrable sender was not frontrun
gvladika Sep 7, 2023
7606ab6
Use chainId in salt for L2 contracts.
gvladika Sep 8, 2023
ee8c5aa
Merge pull request #41 from OffchainLabs/use-chain-id
gvladika Sep 11, 2023
b408bcf
Merge branch 'erc20-based-bridge' into fee-token-deployer
gvladika Sep 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions .env-sample
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
## Goerli - Deploy L1TokenBridgeCreator
ARB_GOERLI_RPC=""
ARB_GOERLI_DEPLOYER_KEY=""
ORBIT_RPC=""
## Rollup on top of which token bridge will be created
ROLLUP_ADDRESS=""
ROLLUP_OWNER=""
L1_TOKEN_BRIDGE_CREATOR=""
# needed for verification
L1_RETRYABLE_SENDER=""

## RPC endpoints
BASECHAIN_RPC=""
ORBIT_RPC=""

## Deployer key used for deploying creator and creating token bridge
BASECHAIN_DEPLOYER_KEY=""
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
.gitignore
.env
node_modules
.vscode/

#Hardhat files
cache
Expand Down
209 changes: 148 additions & 61 deletions contracts/tokenbridge/arbitrum/L2AtomicTokenBridgeFactory.sol

Large diffs are not rendered by default.

525 changes: 389 additions & 136 deletions contracts/tokenbridge/ethereum/L1AtomicTokenBridgeCreator.sol

Large diffs are not rendered by default.

117 changes: 105 additions & 12 deletions contracts/tokenbridge/ethereum/L1TokenBridgeRetryableSender.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,20 @@
pragma solidity ^0.8.4;

import {IInbox} from "@arbitrum/nitro-contracts/src/bridge/IInbox.sol";
import {L2AtomicTokenBridgeFactory, L2RuntimeCode} from "../arbitrum/L2AtomicTokenBridgeFactory.sol";
import {Initializable, OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {
L2AtomicTokenBridgeFactory,
L2RuntimeCode,
ProxyAdmin
} from "../arbitrum/L2AtomicTokenBridgeFactory.sol";
import {
Initializable,
OwnableUpgradeable
} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";
import {TransparentUpgradeableProxy} from
"@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

/**
* @title Token Bridge Retryable Ticket Sender
Expand All @@ -26,13 +38,14 @@ contract L1TokenBridgeRetryableSender is Initializable, OwnableUpgradeable {
* @dev Function will build retryable data, calculate submission cost and retryable value, create retryable
* and then refund the remaining funds to original delpoyer.
*/
function sendRetryable(
function sendRetryableUsingEth(
RetryableParams calldata retryableParams,
L2TemplateAddresses calldata l2,
L1Addresses calldata l1,
L1DeploymentAddresses calldata l1,
address l2StandardGatewayAddress,
address rollupOwner,
address deployer
address deployer,
address aliasedL1UpgradeExecutor
) external payable onlyOwner {
bytes memory data = abi.encodeCall(
L2AtomicTokenBridgeFactory.deployL2Contracts,
Expand All @@ -42,29 +55,75 @@ contract L1TokenBridgeRetryableSender is Initializable, OwnableUpgradeable {
l2.standardGatewayTemplate.code,
l2.customGatewayTemplate.code,
l2.wethGatewayTemplate.code,
l2.wethTemplate.code
l2.wethTemplate.code,
l2.upgradeExecutorTemplate.code,
l2.multicallTemplate.code
),
l1.router,
l1.standardGateway,
l1.customGateway,
l1.wethGateway,
l1.weth,
l2StandardGatewayAddress,
rollupOwner
rollupOwner,
aliasedL1UpgradeExecutor
)
);

uint256 maxSubmissionCost = IInbox(retryableParams.inbox).calculateRetryableSubmissionFee(data.length, 0);
uint256 retryableValue = maxSubmissionCost + retryableParams.maxGas * retryableParams.gasPriceBid;
_createRetryable(retryableParams, maxSubmissionCost, retryableValue, data);
uint256 maxSubmissionCost =
IInbox(retryableParams.inbox).calculateRetryableSubmissionFee(data.length, 0);
uint256 retryableValue =
maxSubmissionCost + retryableParams.maxGas * retryableParams.gasPriceBid;
_createRetryableUsingEth(retryableParams, maxSubmissionCost, retryableValue, data);

// refund excess value to the deployer
uint256 refund = msg.value - retryableValue;
(bool success,) = deployer.call{value: refund}("");
if (!success) revert L1TokenBridgeRetryableSender_RefundFailed();
}

function _createRetryable(
/**
* @notice Creates retryable which deploys L2 side of the token bridge.
* @dev Function will build retryable data, calculate submission cost and retryable value, create retryable
* and then refund the remaining funds to original delpoyer.
*/
function sendRetryableUsingFeeToken(
RetryableParams calldata retryableParams,
L2TemplateAddresses calldata l2,
L1DeploymentAddresses calldata l1,
address l2StandardGatewayAddress,
address rollupOwner,
address aliasedL1UpgradeExecutor
) external payable onlyOwner {
bytes memory data = abi.encodeCall(
L2AtomicTokenBridgeFactory.deployL2Contracts,
(
L2RuntimeCode(
l2.routerTemplate.code,
l2.standardGatewayTemplate.code,
l2.customGatewayTemplate.code,
"",
"",
l2.upgradeExecutorTemplate.code,
l2.multicallTemplate.code
),
l1.router,
l1.standardGateway,
l1.customGateway,
address(0),
address(0),
l2StandardGatewayAddress,
rollupOwner,
aliasedL1UpgradeExecutor
)
);

uint256 retryableFee = retryableParams.maxGas * retryableParams.gasPriceBid;

_createRetryableUsingFeeToken(retryableParams, retryableFee, data);
}

function _createRetryableUsingEth(
RetryableParams calldata retryableParams,
uint256 maxSubmissionCost,
uint256 value,
Expand All @@ -81,6 +140,24 @@ contract L1TokenBridgeRetryableSender is Initializable, OwnableUpgradeable {
data
);
}

function _createRetryableUsingFeeToken(
RetryableParams calldata retryableParams,
uint256 retryableFee,
bytes memory data
) internal {
IERC20Inbox(retryableParams.inbox).createRetryableTicket(
retryableParams.target,
0,
0,
retryableParams.excessFeeRefundAddress,
retryableParams.callValueRefundAddress,
retryableParams.maxGas,
retryableParams.gasPriceBid,
retryableFee,
data
);
}
}

/**
Expand All @@ -104,15 +181,31 @@ struct L2TemplateAddresses {
address customGatewayTemplate;
address wethGatewayTemplate;
address wethTemplate;
address upgradeExecutorTemplate;
address multicallTemplate;
}

/**
* L1 side of token bridge addresses
*/
struct L1Addresses {
struct L1DeploymentAddresses {
address router;
address standardGateway;
address customGateway;
address wethGateway;
address weth;
}

interface IERC20Inbox {
function createRetryableTicket(
address to,
uint256 l2CallValue,
uint256 maxSubmissionCost,
address excessFeeRefundAddress,
address callValueRefundAddress,
uint256 gasLimit,
uint256 maxFeePerGas,
uint256 tokenTotalFeeAmount,
bytes calldata data
) external returns (uint256);
}
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ contract L1OrbitERC20Gateway is L1ERC20Gateway {
/**
* @notice get rollup's native token that's used to pay for fees
*/
function _getNativeFeeToken() internal returns (address) {
function _getNativeFeeToken() internal view returns (address) {
address bridge = address(getBridge(inbox));
return IERC20Bridge(bridge).nativeToken();
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/tokenbridge/libraries/IERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ interface IERC20Bridge {
/**
* @dev token that is escrowed in bridge on L1 side and minted on L2 as native currency. Also fees are paid in this token.
*/
function nativeToken() external returns (address);
function nativeToken() external view returns (address);
}
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ libs = ["node_modules", "lib"]
test = 'test-foundry'
cache_path = 'forge-cache'
optimizer = true
optimizer_runs = 20000
optimizer_runs = 100
via_ir = false

[fmt]
Expand Down
2 changes: 1 addition & 1 deletion hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const config = {
},
},
{
version: '0.8.17',
version: '0.8.16',
settings: {
optimizer: {
enabled: true,
Expand Down
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
"test:unit": "forge test",
"test:e2e:local-env": "yarn hardhat test test-e2e/*",
"test:storage": "./scripts/storage_layout_test.bash",
"deploy:orbit-tokenbridge:script": "ts-node ./scripts/local-deployment/orbitTokenBridgeDeployer.ts",
"deploy:local:token-bridge": "ts-node ./scripts/local-deployment/deploy.ts",
"deploy:local:token-bridge": "ts-node ./scripts/local-deployment/deployCreatorAndCreateTokenBridge.ts",
"deploy:goerli:token-bridge-creator": "ts-node ./scripts/goerli-deployment/deployTokenBridgeCreator.ts",
"create:goerli:token-bridge": "ts-node ./scripts/goerli-deployment/createTokenBridge.ts",
"test:tokenbridge:deployment": "hardhat test test-e2e/tokenBridgeDeploymentTest.ts",
Expand All @@ -39,9 +38,9 @@
],
"dependencies": {
"@arbitrum/nitro-contracts": "^1.0.0-beta.8",
"@arbitrum/sdk": "^3.1.5",
"@openzeppelin/contracts": "4.8.3",
"@openzeppelin/contracts-upgradeable": "4.8.3"
"@openzeppelin/contracts-upgradeable": "4.8.3",
"@offchainlabs/upgrade-executor": "^1.0.0-beta.2"
},
"devDependencies": {
"@arbitrum/sdk": "^3.1.3",
Expand Down
Loading
Loading