Commit a0611ce6 authored by luxq's avatar luxq

add files

parent 6e91ef32
PRIVATE_KEY=0xYOURPRIVATEKEY
\ No newline at end of file
node_modules
.env
# Hardhat files
/cache
/artifacts
# TypeChain files
/typechain
/typechain-types
# solidity-coverage files
/coverage
/coverage.json
# Hardhat Ignition default folder for deployments against a local node
ignition/deployments/chain-31337
# erc20bridge
Bridge erc20 token from L1 to L2 via gas token portal.
## Install dependencies
1. install nvm and use node v20.
```shell
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc # if you used zsh, please replace .bashrc with .zshrc
nvm install v20
nvm use v20
```
2. clone code and install packages.
```shell
git clone https://code.wuban.net.cn/exchain/erc20bridge
cd erc20bridge
npm install --save-dev hardhat
npm install
```
## How to deploy token ?
#### 1. Copy `.env.example` to `.env` and fill in the environment variables.
#### 2. Change token name and symbol in `deploy.js`.
#### 3. Run command `npx hardhat run scripts/deploy.js --network test` to deploy token.
## How to bridge token ?
#### 1. Fill in the `account.json` file with the accounts you want to bridge.
#### 2. Fill in the `bridge.js` file with the token address and portal address.
#### 3. Run command `npx hardhat run scripts/bridge.js --network test` to bridge token.
[{"type":"constructor","inputs":[],"stateMutability":"nonpayable"},{"type":"receive","stateMutability":"payable"},{"type":"function","name":"balance","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"depositERC20Transaction","inputs":[{"name":"_to","type":"address","internalType":"address"},{"name":"_mint","type":"uint256","internalType":"uint256"},{"name":"_value","type":"uint256","internalType":"uint256"},{"name":"_gasLimit","type":"uint64","internalType":"uint64"},{"name":"_isCreation","type":"bool","internalType":"bool"},{"name":"_data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"depositTransaction","inputs":[{"name":"_to","type":"address","internalType":"address"},{"name":"_value","type":"uint256","internalType":"uint256"},{"name":"_gasLimit","type":"uint64","internalType":"uint64"},{"name":"_isCreation","type":"bool","internalType":"bool"},{"name":"_data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"donateETH","inputs":[],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"finalizeWithdrawalTransaction","inputs":[{"name":"_tx","type":"tuple","internalType":"struct Types.WithdrawalTransaction","components":[{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"sender","type":"address","internalType":"address"},{"name":"target","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"},{"name":"gasLimit","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"finalizedWithdrawals","inputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"guardian","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"initialize","inputs":[{"name":"_l2Oracle","type":"address","internalType":"contract L2OutputOracle"},{"name":"_systemConfig","type":"address","internalType":"contract SystemConfig"},{"name":"_superchainConfig","type":"address","internalType":"contract SuperchainConfig"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"isOutputFinalized","inputs":[{"name":"_l2OutputIndex","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"l2Oracle","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract L2OutputOracle"}],"stateMutability":"view"},{"type":"function","name":"l2Sender","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"minimumGasLimit","inputs":[{"name":"_byteCount","type":"uint64","internalType":"uint64"}],"outputs":[{"name":"","type":"uint64","internalType":"uint64"}],"stateMutability":"pure"},{"type":"function","name":"params","inputs":[],"outputs":[{"name":"prevBaseFee","type":"uint128","internalType":"uint128"},{"name":"prevBoughtGas","type":"uint64","internalType":"uint64"},{"name":"prevBlockNum","type":"uint64","internalType":"uint64"}],"stateMutability":"view"},{"type":"function","name":"paused","inputs":[],"outputs":[{"name":"paused_","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"proveWithdrawalTransaction","inputs":[{"name":"_tx","type":"tuple","internalType":"struct Types.WithdrawalTransaction","components":[{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"sender","type":"address","internalType":"address"},{"name":"target","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"},{"name":"gasLimit","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}]},{"name":"_l2OutputIndex","type":"uint256","internalType":"uint256"},{"name":"_outputRootProof","type":"tuple","internalType":"struct Types.OutputRootProof","components":[{"name":"version","type":"bytes32","internalType":"bytes32"},{"name":"stateRoot","type":"bytes32","internalType":"bytes32"},{"name":"messagePasserStorageRoot","type":"bytes32","internalType":"bytes32"},{"name":"latestBlockhash","type":"bytes32","internalType":"bytes32"}]},{"name":"_withdrawalProof","type":"bytes[]","internalType":"bytes[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"provenWithdrawals","inputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"outputRoot","type":"bytes32","internalType":"bytes32"},{"name":"timestamp","type":"uint128","internalType":"uint128"},{"name":"l2OutputIndex","type":"uint128","internalType":"uint128"}],"stateMutability":"view"},{"type":"function","name":"setGasPayingToken","inputs":[{"name":"_token","type":"address","internalType":"address"},{"name":"_decimals","type":"uint8","internalType":"uint8"},{"name":"_name","type":"bytes32","internalType":"bytes32"},{"name":"_symbol","type":"bytes32","internalType":"bytes32"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"superchainConfig","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract SuperchainConfig"}],"stateMutability":"view"},{"type":"function","name":"systemConfig","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract SystemConfig"}],"stateMutability":"view"},{"type":"function","name":"version","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"pure"},{"type":"event","name":"Initialized","inputs":[{"name":"version","type":"uint8","indexed":false,"internalType":"uint8"}],"anonymous":false},{"type":"event","name":"TransactionDeposited","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"version","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"opaqueData","type":"bytes","indexed":false,"internalType":"bytes"}],"anonymous":false},{"type":"event","name":"WithdrawalFinalized","inputs":[{"name":"withdrawalHash","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"success","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"type":"event","name":"WithdrawalProven","inputs":[{"name":"withdrawalHash","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"error","name":"BadTarget","inputs":[]},{"type":"error","name":"CallPaused","inputs":[]},{"type":"error","name":"ContentLengthMismatch","inputs":[]},{"type":"error","name":"EmptyItem","inputs":[]},{"type":"error","name":"GasEstimation","inputs":[]},{"type":"error","name":"InvalidDataRemainder","inputs":[]},{"type":"error","name":"InvalidHeader","inputs":[]},{"type":"error","name":"LargeCalldata","inputs":[]},{"type":"error","name":"NoValue","inputs":[]},{"type":"error","name":"NonReentrant","inputs":[]},{"type":"error","name":"OnlyCustomGasToken","inputs":[]},{"type":"error","name":"OutOfGas","inputs":[]},{"type":"error","name":"SmallGasLimit","inputs":[]},{"type":"error","name":"TransferFailed","inputs":[]},{"type":"error","name":"Unauthorized","inputs":[]},{"type":"error","name":"UnexpectedList","inputs":[]},{"type":"error","name":"UnexpectedString","inputs":[]}]
\ No newline at end of file
[
{
"inputs": [
{
"internalType": "uint256",
"name": "initialSupply",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "decimals",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "subtractedValue",
"type": "uint256"
}
],
"name": "decreaseAllowance",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "addedValue",
"type": "uint256"
}
],
"name": "increaseAllowance",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "mint",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
}
]
\ No newline at end of file
[
{"address":"","private":"0x", "amount": 100},
{"address":"","private":"0x", "amount": 1},
{"address":"","private":"0x", "amount": 10}
]
\ No newline at end of file
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract GasToken is ERC20 {
constructor(uint256 initialSupply, string memory name, string memory symbol) ERC20(name, symbol) {
_mint(msg.sender, initialSupply);
}
function mint(address to, uint256 amount) public {
_mint(to, amount * 10 **this.decimals());
}
}
\ No newline at end of file
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();
// Define mnemonic for accounts.
let mnemonic = "test test test test test test test test test test test test"
const accounts = { mnemonic }
// checkout private key env, if env is set, use it as accounts.
if (process.env.PRIVATE_KEY) {
accounts.accounts = [process.env.PRIVATE_KEY]
}
module.exports = {
solidity: {
version: "0.8.10",
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
networks: {
test:{
accounts,
url: "http://127.0.0.1:8545",
},
},
};
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "hardhat-project",
"devDependencies": {
"@nomicfoundation/hardhat-toolbox": "^5.0.0",
"hardhat": "^2.22.19"
},
"dependencies": {
"@openzeppelin/contracts": "^4.9.6",
"dotenv": "^16.4.7"
}
}
const { ethers } = require("hardhat");
const tokenABI = require("../abi/token.json");
const portalABI = require("../abi/portal.json");
async function bridge(users, portalAddr, tokenAddr) {
const provider = ethers.provider;
const portalContract = new ethers.Contract(portalAddr, portalABI, provider);
const tokenContract = new ethers.Contract(tokenAddr, tokenABI, provider);
for (let i = 0; i < users.length; i++) {
const privateKey = users[i]["private"];
const user = users[i]["address"];
const value = ethers.parseEther(users[i]["amount"])
const signer = new ethers.Wallet(privateKey, provider);
const contractWithSigner = portalContract.connect(signer);
const usdxWithSigner = tokenContract.connect(signer);
const approve = await usdxWithSigner.approve(portalAddr, value);
await approve.wait();
console.log("approve token to portal contract tx hash:", approve.hash);
const deposit = await contractWithSigner.depositERC20Transaction(user, value, value, 0, false, "");
await deposit.wait();
console.log("deposit tx hash:", deposit.hash, " for user:", user);
}
}
async function main() {
const users = require("../account.json")
const portalAddr = "";
const usdxTokenAddr = ""
await bridge(users, portalAddr, usdxTokenAddr);
}
main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
\ No newline at end of file
const { ethers } = require("hardhat");
async function deploy() {
const GasToken = await ethers.getContractFactory("GasToken");
const usdxToken = await GasToken.deploy(100000000000, "USDX", "USDX");
await usdxToken.waitForDeployment();
const usdxTokenAddress = await usdxToken.getAddress();
console.log("USDX deployed to:", usdxTokenAddress);
return usdxToken
}
async function main() {
[owner] = await ethers.getSigners();
console.log("start scripts with owner:", owner.address);
await deploy();
}
main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment