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

Deployment scripts #3

Merged
merged 20 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
38 changes: 32 additions & 6 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,11 +1,37 @@
export API_KEY_ALCHEMY="YOUR_API_KEY_ALCHEMY"
export API_KEY_ARBISCAN="YOUR_API_KEY_ARBISCAN"
export API_KEY_BSCSCAN="YOUR_API_KEY_BSCSCAN"
export API_KEY_ETHERSCAN="YOUR_API_KEY_ETHERSCAN"
export API_KEY_GNOSISSCAN="YOUR_API_KEY_GNOSISSCAN"
export API_KEY_INFURA="YOUR_API_KEY_INFURA"
export API_KEY_OPTIMISTIC_ETHERSCAN="YOUR_API_KEY_OPTIMISTIC_ETHERSCAN"
export API_KEY_POLYGONSCAN="YOUR_API_KEY_POLYGONSCAN"
export API_KEY_SNOWTRACE="YOUR_API_KEY_SNOWTRACE"
export MNEMONIC="YOUR_MNEMONIC"
export FOUNDRY_PROFILE="default"

export DEPLOYER_PK="your deployer private key"
export DEPLOYER_ADDRESS="your deployer address"

export SEPOLIA_RPC_URL="some sepolia RPC URL"
export ARBITRUM_SEPOLIA_RPC_URL="some arbitrum sepolia RPC URL"
export ETHERSCAN_API_KEY="your etherscan api key"
export ARBISCAN_API_KEY="your arbican api key"

export XERC20_FACTORY="0x89c1ffFc94Fd0FAb9F98bC58cCA884B5dF1dA437"
export XERC20_NAME="XERC20 TEST"
export XERC20_SYMBOL="XERC20 TEST"
# max uint256 / 2
export XERC20_BURN_MINT_LIMITS=115792089237316195423570985008687907853269984665640564039457584007913129639935
export XERC20_BRIDGES="addresses separated by coma"

export CREATE3_FACTORY="address of the CREATE3Factory"

export L1_GATEWAY_OWNER="L1 gateway owner address"
export L1_ARBITRUM_ROUTER="address of L1 arbitrum rounter contract"
export L1_ARBITRUM_INBOX="address of L1 arbitrum inbox contract"

export L1_XERC20="the address of some XERC20 token on L1"
export L1_GATEWAY="the L1XERC20Gateway address"
export L1_ADAPTER_OWNER="L1 adapter owner address"
export L1_ADAPTER="L1 adapter address"

export L2_ADAPTER_OWNER="0x0f9530A85D8fCfA9a2a2E2d7Ffe9786Faf6a71cA"
export L2_GATEWAY="the L2XERC20Gateway address"
export L2_ARBITRUM_ROUTER="address of L2 arbitrum rounter contract"
export L2_XERC20="the address of some XERC20 token on L2"
export L2_ADAPTER="L2 adapter address"
Binary file modified bun.lockb
Binary file not shown.
16 changes: 3 additions & 13 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,9 @@

[etherscan]
arbitrum = { key = "${API_KEY_ARBISCAN}" }
avalanche = { key = "${API_KEY_SNOWTRACE}" }
bnb_smart_chain = { key = "${API_KEY_BSCSCAN}" }
gnosis_chain = { key = "${API_KEY_GNOSISSCAN}" }
goerli = { key = "${API_KEY_ETHERSCAN}" }
mainnet = { key = "${API_KEY_ETHERSCAN}" }
optimism = { key = "${API_KEY_OPTIMISTIC_ETHERSCAN}" }
polygon = { key = "${API_KEY_POLYGONSCAN}" }
sepolia = { key = "${API_KEY_ETHERSCAN}" }
arbitrum-sepolia = { key = "${API_KEY_ARBISCAN}", url = "https://api-sepolia.arbiscan.io/api" }

[fmt]
bracket_spacing = true
Expand All @@ -45,13 +40,8 @@
# arbitrum = "https://arbitrum-mainnet.infura.io/v3/${API_KEY_INFURA}"
# arbitrum = "https://rpc.ankr.com/arbitrum"
arbitrum = "https://arbitrum.llamarpc.com"
avalanche = "https://avalanche-mainnet.infura.io/v3/${API_KEY_INFURA}"
bnb_smart_chain = "https://bsc-dataseed.binance.org"
gnosis_chain = "https://rpc.gnosischain.com"
goerli = "https://goerli.infura.io/v3/${API_KEY_INFURA}"
localhost = "http://localhost:8545"
# mainnet = "https://eth-mainnet.g.alchemy.com/v2/${API_KEY_ALCHEMY}"
mainnet = "https://eth.llamarpc.com"
optimism = "https://optimism-mainnet.infura.io/v3/${API_KEY_INFURA}"
polygon = "https://polygon-mainnet.infura.io/v3/${API_KEY_INFURA}"
sepolia = "https://sepolia.infura.io/v3/${API_KEY_INFURA}"
sepolia = "https://eth-sepolia.g.alchemy.com/v2/${API_KEY_ALCHEMY}"
arbitrum-sepolia = "${ARBITRUM_SEPOLIA_RPC_URL}"
24 changes: 23 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@
"dependencies": {
"@arbitrum/token-bridge-contracts": "github:OffchainLabs/token-bridge-contracts",
"@openzeppelin/contracts": "^4.9.6",
"solmate": "github:transmissions11/solmate",
"xerc20": "github:defi-wonderland/xERC20"
},
"devDependencies": {
"dotenv": "^16.4.5",
"dotenv-run-script": "^0.4.1",
"forge-std": "github:foundry-rs/forge-std#v1.8.1",
"prettier": "^3.0.0",
"solhint": "^3.6.2"
Expand All @@ -22,10 +25,29 @@
"build": "forge build",
"lint": "bun run lint:sol && bun run prettier:check",
"lint:sol": "forge fmt --check && bun solhint {script,src,test}/**/*.sol",
"sol:fmt": "forge fmt",
"prettier:check": "prettier --check \"**/*.{json,md,yml}\" --ignore-path \".prettierignore\"",
"prettier:write": "prettier --write \"**/*.{json,md,yml}\" --ignore-path \".prettierignore\"",
"test": "forge test",
"test:coverage": "forge coverage",
"test:coverage:report": "forge coverage --report lcov && genhtml lcov.info --branch-coverage --output-dir coverage"
"test:coverage:report": "forge coverage --report lcov && genhtml lcov.info --branch-coverage --output-dir coverage",
"factory:sepolia": "forge script script/XERC20/XERC20Factory.s.sol:XERC20FactoryDeploy --rpc-url $SEPOLIA_RPC_URL --broadcast --verify --etherscan-api-key $ETHERSCAN_API_KEY --chain sepolia -vvvv",
"deploy:factory:sepolia": "dotenv-run-script factory:sepolia",
"factory:arb:sepolia": "forge script script/XERC20/XERC20Factory.s.sol:XERC20FactoryDeploy -f arbitrum-sepolia -vvvv --broadcast --verify --skip-simulation",
"deploy:factory:arb:sepolia": "dotenv-run-script factory:arb:sepolia",
"token:sepolia": "forge script script/XERC20/XERC20.s.sol:XERC20Deploy --rpc-url $SEPOLIA_RPC_URL --broadcast --verify --etherscan-api-key $ETHERSCAN_API_KEY --chain sepolia -vvvv",
"deploy:token:sepolia": "dotenv-run-script token:sepolia",
"token:arb:sepolia": "forge script script/XERC20/XERC20.s.sol:XERC20Deploy -f arbitrum-sepolia --broadcast --verify --etherscan-api-key $ARBISCAN_API_KEY --chain arbitrum-sepolia -vvvv",
"deploy:token:arb:sepolia": "dotenv-run-script token:arb:sepolia",
"gateway:sepolia": "forge script script/L1Gateway.s.sol:L1GatewayDeploy --rpc-url $SEPOLIA_RPC_URL --broadcast --verify --etherscan-api-key $ETHERSCAN_API_KEY --chain sepolia -vvvv",
"deploy:gateway:sepolia": "dotenv-run-script gateway:sepolia",
"gateway:arb:sepolia": "forge script script/L2Gateway.s.sol:L2GatewayDeploy -f arbitrum-sepolia --broadcast --verify --etherscan-api-key $ARBISCAN_API_KEY --chain arbitrum-sepolia -vvvv",
"deploy:gateway:arb:sepolia": "dotenv-run-script gateway:arb:sepolia",
"adapter:sepolia": "forge script script/L1Adapter.s.sol:L1AdapterDeploy --rpc-url $SEPOLIA_RPC_URL --broadcast --verify --etherscan-api-key $ETHERSCAN_API_KEY --chain sepolia -vvvv",
"deploy:adapter:sepolia": "dotenv-run-script adapter:sepolia",
"adapter:arb:sepolia": "forge script script/L2Adapter.s.sol:L2AdapterDeploy -f arbitrum-sepolia --broadcast --verify --etherscan-api-key $ARBISCAN_API_KEY --chain arbitrum-sepolia -vvvv",
"deploy:adapter:arb:sepolia": "dotenv-run-script adapter:arb:sepolia",
"register:sepolia": "forge script script/L1AdapterRegister.s.sol:L1AdapterRegister --rpc-url $SEPOLIA_RPC_URL --broadcast -vvvv",
"run:register:sepolia": "dotenv-run-script register:sepolia"
}
}
1 change: 1 addition & 0 deletions remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
forge-std/=node_modules/forge-std/src/
xerc20/=node_modules/xerc20/solidity/
solmate/=node_modules/solmate/src/
isolmate/=node_modules/solmate/src/
12 changes: 0 additions & 12 deletions script/Deploy.s.sol

This file was deleted.

30 changes: 30 additions & 0 deletions script/L1Adapter.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.25 <0.9.0;

import { Script } from "forge-std/Script.sol";
import { L1XERC20Adapter } from "src/L1XERC20Adapter.sol";
import { ICREATE3Factory } from "./utils/ICREATE3Factory.sol";

import { console2 } from "forge-std/console2.sol";

contract L1AdapterDeploy is Script {
string public constant SALT = "XERC20Adapter-v0.3";

function run() public {
uint256 deployerPrivateKey = vm.envUint("DEPLOYER_PK");
address create3Fatory = vm.envAddress("CREATE3_FACTORY");
lmcorbalan marked this conversation as resolved.
Show resolved Hide resolved

address owner = vm.envAddress("L1_ADAPTER_OWNER");
address token = vm.envAddress("L1_XERC20");
address gateway = vm.envAddress("L1_GATEWAY");

bytes32 _salt = keccak256(abi.encodePacked(SALT, vm.addr(deployerPrivateKey)));

bytes memory _creation = type(L1XERC20Adapter).creationCode;
bytes memory _bytecode = abi.encodePacked(_creation, abi.encode(token, gateway, owner));

ICREATE3Factory(create3Fatory).deploy(_salt, _bytecode);

vm.stopBroadcast();
}
}
38 changes: 38 additions & 0 deletions script/L1AdapterRegister.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.25 <0.9.0;

import { Script } from "forge-std/Script.sol";
import { L1XERC20Adapter } from "src/L1XERC20Adapter.sol";

contract L1AdapterRegister is Script {
function run() public {
uint256 deployerPrivateKey = vm.envUint("DEPLOYER_PK");

L1XERC20Adapter adapter = L1XERC20Adapter(vm.envAddress("L1_ADAPTER"));
address l2TokenAddress = vm.envAddress("L2_ADAPTER");
uint256 maxSubmissionCostForGateway = 100_000_000_000_000_000;
uint256 maxSubmissionCostForRouter = 100_000_000_000_000_000;
uint256 maxGasForGateway = 2_000_000;
uint256 maxGasForRouter = 2_000_000;
uint256 gasPriceBid = 1_011_990_000;
uint256 valueForGateway = 110_000_000_000_000_000;
uint256 valueForRouter = 110_000_000_000_000_000;
address creditBackAddress = vm.envAddress("DEPLOYER_ADDRESS");

vm.startBroadcast(deployerPrivateKey);

adapter.registerTokenOnL2{ value: 220_000_000_000_000_000 }(
l2TokenAddress,
maxSubmissionCostForGateway,
maxSubmissionCostForRouter,
maxGasForGateway,
maxGasForRouter,
gasPriceBid,
valueForGateway,
valueForRouter,
creditBackAddress
);

vm.stopBroadcast();
}
}
29 changes: 29 additions & 0 deletions script/L1Gateway.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.25 <0.9.0;

import { Script } from "forge-std/Script.sol";
import { L1XERC20Gateway } from "src/L1XERC20Gateway.sol";
import { ICREATE3Factory } from "./utils/ICREATE3Factory.sol";

contract L1GatewayDeploy is Script {
string public constant SALT = "XERC20Gateway-v0.3";

function run() public {
uint256 deployerPrivateKey = vm.envUint("DEPLOYER_PK");
address create3Fatory = vm.envAddress("CREATE3_FACTORY");
address owner = vm.envAddress("L1_GATEWAY_OWNER");
address router = vm.envAddress("L1_ARBITRUM_ROUTER");
address inbox = vm.envAddress("L1_ARBITRUM_INBOX");

vm.startBroadcast(deployerPrivateKey);

bytes32 _salt = keccak256(abi.encodePacked(SALT, vm.addr(deployerPrivateKey)));

bytes memory _creation = type(L1XERC20Gateway).creationCode;
bytes memory _bytecode = abi.encodePacked(_creation, abi.encode(owner, router, inbox));

ICREATE3Factory(create3Fatory).deploy(_salt, _bytecode);

vm.stopBroadcast();
}
}
31 changes: 31 additions & 0 deletions script/L2Adapter.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.25 <0.9.0;

import { Script } from "forge-std/Script.sol";
import { L2XERC20Adapter } from "src/L2XERC20Adapter.sol";
import { ICREATE3Factory } from "./utils/ICREATE3Factory.sol";

contract L2AdapterDeploy is Script {
string public constant SALT = "XERC20Adapter-v0.3";

function run() public {
uint256 deployerPrivateKey = vm.envUint("DEPLOYER_PK");
address create3Fatory = vm.envAddress("CREATE3_FACTORY");

address owner = vm.envAddress("L2_ADAPTER_OWNER");
address token = vm.envAddress("L2_XERC20");
address gateway = vm.envAddress("L2_GATEWAY");
address l1Adapter = vm.envAddress("L1_ADAPTER");

vm.startBroadcast(deployerPrivateKey);

bytes32 _salt = keccak256(abi.encodePacked(SALT, vm.addr(deployerPrivateKey)));

bytes memory _creation = type(L2XERC20Adapter).creationCode;
bytes memory _bytecode = abi.encodePacked(_creation, abi.encode(token, gateway, l1Adapter, owner));

ICREATE3Factory(create3Fatory).deploy(_salt, _bytecode);

vm.stopBroadcast();
}
}
28 changes: 28 additions & 0 deletions script/L2Gateway.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.25 <0.9.0;

import { Script } from "forge-std/Script.sol";
import { L2XERC20Gateway } from "src/L2XERC20Gateway.sol";
import { ICREATE3Factory } from "./utils/ICREATE3Factory.sol";

contract L2GatewayDeploy is Script {
string public constant SALT = "XERC20Gateway-v0.3";

function run() public {
uint256 deployerPrivateKey = vm.envUint("DEPLOYER_PK");
address create3Fatory = vm.envAddress("CREATE3_FACTORY");
address router = vm.envAddress("L2_ARBITRUM_ROUTER");
address l1Counterpart = vm.envAddress("L1_GATEWAY");

vm.startBroadcast(deployerPrivateKey);

bytes32 _salt = keccak256(abi.encodePacked(SALT, vm.addr(deployerPrivateKey)));

bytes memory _creation = type(L2XERC20Gateway).creationCode;
bytes memory _bytecode = abi.encodePacked(_creation, abi.encode(l1Counterpart, router));

ICREATE3Factory(create3Fatory).deploy(_salt, _bytecode);

vm.stopBroadcast();
}
}
26 changes: 26 additions & 0 deletions script/XERC20/XERC20.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.25 <0.9.0;

import { Script } from "forge-std/Script.sol";
import { XERC20Factory } from "xerc20/contracts/XERC20Factory.sol";

contract XERC20Deploy is Script {
function run() public {
uint256 deployerPrivateKey = vm.envUint("DEPLOYER_PK");

address factoryAdrress = vm.envAddress("XERC20_FACTORY");
string memory name = vm.envString("XERC20_NAME");
string memory symbol = vm.envString("XERC20_SYMBOL");

uint256[] memory limits = vm.envOr("XERC20_BURN_MINT_LIMITS", ",", new uint256[](0));
address[] memory bridges = vm.envOr("XERC20_BRIDGES", ",", new address[](0));

limits[0] = type(uint256).max / 2;

vm.startBroadcast(deployerPrivateKey);

XERC20Factory(factoryAdrress).deployXERC20(name, symbol, limits, limits, bridges);

vm.stopBroadcast();
}
}
21 changes: 21 additions & 0 deletions script/XERC20/XERC20Factory.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.25 <0.9.0;

import { Script } from "forge-std/Script.sol";
import { XERC20Factory } from "xerc20/contracts/XERC20Factory.sol";

contract XERC20FactoryDeploy is Script {
string public constant SALT = "xERC20-v1.5";

function run() public {
uint256 deployerPrivateKey = vm.envUint("DEPLOYER_PK");

vm.startBroadcast(deployerPrivateKey);

bytes32 _salt = keccak256(abi.encodePacked(SALT, msg.sender));

new XERC20Factory{ salt: _salt }();

vm.stopBroadcast();
}
}
22 changes: 22 additions & 0 deletions script/utils/ICREATE3Factory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.25 <0.9.0;

/// @title Factory for deploying contracts to deterministic addresses via CREATE3
/// @author zefram.eth
/// @notice Enables deploying contracts using CREATE3. Each deployer (msg.sender) has
/// its own namespace for deployed addresses.
interface ICREATE3Factory {
/// @notice Deploys a contract using CREATE3
/// @dev The provided salt is hashed together with msg.sender to generate the final salt
/// @param salt The deployer-specific salt for determining the deployed contract's address
/// @param creationCode The creation code of the contract to deploy
/// @return deployed The address of the deployed contract
function deploy(bytes32 salt, bytes memory creationCode) external payable returns (address deployed);

/// @notice Predicts the address of a deployed contract
/// @dev The provided salt is hashed together with the deployer address to generate the final salt
/// @param deployer The deployer account that will call deploy()
/// @param salt The deployer-specific salt for determining the deployed contract's address
/// @return deployed The address of the contract that will be deployed
function getDeployed(address deployer, bytes32 salt) external view returns (address deployed);
}
8 changes: 7 additions & 1 deletion src/L1XERC20Adapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ import { XERC20BaseAdapter } from "src/XERC20BaseAdapter.sol";
import { L1XERC20Gateway } from "src/L1XERC20Gateway.sol";

contract L1XERC20Adapter is XERC20BaseAdapter {
constructor(address _xerc20, address _gatewayAddress) XERC20BaseAdapter(_xerc20, _gatewayAddress) { }
constructor(
address _xerc20,
address _gatewayAddress,
address _owner
)
XERC20BaseAdapter(_xerc20, _gatewayAddress, _owner)
{ }

function isArbitrumEnabled() external pure returns (uint8) {
return uint8(0xb1);
Expand Down
4 changes: 2 additions & 2 deletions src/L1XERC20Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { XERC20BaseGateway } from "src/XERC20BaseGateway.sol";
* @title Gateway for xERC20 bridging functionality
*/
contract L1XERC20Gateway is XERC20BaseGateway, L1CustomGateway {
constructor(address _l1Router, address _inbox) {
constructor(address _l1Router, address _inbox, address _owner) {
address _l2Counterpart = address(this);
initialize(_l2Counterpart, _l1Router, _inbox, msg.sender);
initialize(_l2Counterpart, _l1Router, _inbox, _owner);
}

function outboundEscrowTransfer(
Expand Down
Loading