Skip to content

Commit

Permalink
Merge pull request #47 from lightlink-network/feat/add-foundry
Browse files Browse the repository at this point in the history
Fix: bridge deployment
  • Loading branch information
CryptoKass authored Aug 1, 2024
2 parents 0586ed5 + 15d68a8 commit 7726b3c
Show file tree
Hide file tree
Showing 15 changed files with 148 additions and 126 deletions.
7 changes: 5 additions & 2 deletions contracts/L1/LightLinkPortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ contract LightLinkPortal is Initializable, ResourceMetering, Ownable, Pausable {
constructor() Pausable(msg.sender) {
initialize({
_l2Oracle: ICanonicalStateChain(address(0)),
_challenge: IChallengeBase(address(0))
_challenge: IChallengeBase(address(0)),
_newOwner: address(0)
});
}

Expand All @@ -124,7 +125,8 @@ contract LightLinkPortal is Initializable, ResourceMetering, Ownable, Pausable {
/// @param _challenge Contract of the ChallengeBase.
function initialize(
ICanonicalStateChain _l2Oracle,
IChallengeBase _challenge
IChallengeBase _challenge,
address _newOwner
) public initializer {
l2Oracle = _l2Oracle;
challenge = _challenge;
Expand All @@ -139,6 +141,7 @@ contract LightLinkPortal is Initializable, ResourceMetering, Ownable, Pausable {
if (l2Sender == address(0)) {
l2Sender = Constants.DEFAULT_L2_SENDER;
}
_transferOwnership(_newOwner);
__ResourceMetering_init();
}

Expand Down

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions scripts/forge/deploy-config/devnet.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"l2ChainID": 88,
"proxyAdminOwner": "0x17030FA319f1615FD6c407DC0f44981d1E0f44DB",
"l1CrossDomainMessengerProxy": "0x3fCa2E0b13BdbC51e613d237f8b031E00A6892de",
"l1StandardBridgeProxy": "0x90FC2B871907b91fA70Ba7d1420Bd813Bcad7CC3"
"l1CrossDomainMessengerProxy": "0xfefc822525263Ba6A0EE88d76B73E225ACC48809",
"l1StandardBridgeProxy": "0xe4d23cB0A80dC843df000a13329266a011B22614"
}
8 changes: 4 additions & 4 deletions scripts/forge/deploy-config/pegasus.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"l2ChainID": 10,
"proxyAdminOwner": "0x7871d1187A97cbbE40710aC119AA3d412944e4Fe",
"l1CrossDomainMessengerProxy": "0x7871d1187A97cbbE40710aC119AA3d412944e4Fe",
"l1StandardBridgeProxy": "0x7871d1187A97cbbE40710aC119AA3d412944e4Fe"
"l2ChainID": 1891,
"proxyAdminOwner": "0x6D7fa51685640B415154d054A469dfB6E9af263a",
"l1CrossDomainMessengerProxy": "0x647BC47a449a422C27a40F6D60785ca0bb5A61F5",
"l1StandardBridgeProxy": "0xA8460b2f3cc5B31E5DEeE1e9e553Afca1317E9DC"
}
17 changes: 10 additions & 7 deletions scripts/hardhat/deploy/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { verify } from "../../utils/verify";
import { log } from "../lib/log";
import {
createGenesisHeader,
proxyDeployAndInitialize,
uupsProxyDeployAndInitialize,
getBlobstreamXAddr,
} from "../lib/deploy";

Expand All @@ -18,8 +18,9 @@ const main = async () => {

// Step 1. Get deployer/signer account
let [owner, publisher] = await ethers.getSigners();
if (publisher === undefined) { // somestimes if owner, and publisher are the same, publisher is undefined
log("Publisher account not found. Using owner account as publisher.")
if (publisher === undefined) {
// somestimes if owner, and publisher are the same, publisher is undefined
log("Publisher account not found. Using owner account as publisher.");
publisher = owner;
}

Expand All @@ -36,30 +37,32 @@ const main = async () => {

// Step 3. Deploy CanonicalStateChain contract as proxy
log("Deploying CanonicalStateChain...");
const canonicalStateChain = await proxyDeployAndInitialize(
const canonicalStateChain = await uupsProxyDeployAndInitialize(
owner,
await ethers.getContractFactory("CanonicalStateChain"),
[publisherAddr, genesisHeader],
);

// Step 4. Deploy required RLPReader lib
log("Deploying RLPReader...");
const RLPReader = await ethers.getContractFactory("contracts/L1/RLPReader.sol:RLPReader");
const RLPReader = await ethers.getContractFactory(
"contracts/L1/RLPReader.sol:RLPReader",
);
const rlpReader = await RLPReader.deploy();
await rlpReader.waitForDeployment();
const rlpReaderAddr = await rlpReader.getAddress();

// Step 5. Deploying ChainOracle contract as a proxy
log("Deploying ChainOracle...");
const chainOracle = await proxyDeployAndInitialize(
const chainOracle = await uupsProxyDeployAndInitialize(
owner,
await ethers.getContractFactory("ChainOracle"),
[canonicalStateChain.address, blobstreamXAddr, rlpReaderAddr],
);

// Step 6. Deploy Challenge contract as a proxy
log("Deploying Challenge...");
const challenge = await proxyDeployAndInitialize(
const challenge = await uupsProxyDeployAndInitialize(
owner,
await ethers.getContractFactory("Challenge"),
[canonicalStateChain.address, blobstreamXAddr, chainOracle.address],
Expand Down
2 changes: 1 addition & 1 deletion scripts/hardhat/deploy/deployBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const main = async () => {
const lightLinkPortal = await proxyDeployAndInitialize(
l1Deployer,
await ethers.getContractFactory("LightLinkPortal"),
[CanonicalStateChain, Challenge],
[CanonicalStateChain, Challenge, l1Deployer.address],
);

// Deploy L1CrossDomainMessenger contract to L1
Expand Down
11 changes: 7 additions & 4 deletions scripts/hardhat/deploy/deployTestnet.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { ethers } from "hardhat";
import { setupCanonicalStateChain } from "../../test/lib/chain";
import { setupCanonicalStateChain } from "../../../test/lib/chain";
import {
Challenge,
LightLinkPortal,
L2CrossDomainMessenger,
L1CrossDomainMessenger,
} from "../../typechain-types";
import { proxyDeployAndInitialize } from "../lib/deploy";
} from "../../../typechain-types";
import {
proxyDeployAndInitialize,
uupsProxyDeployAndInitialize,
} from "../lib/deploy";
import { startNetworks } from "../lib/startNetworks";

const main = async () => {
Expand All @@ -33,7 +36,7 @@ const main = async () => {
console.log("CanonicalStateChain deployed");

// - Challenge
const challengeDeployment = await proxyDeployAndInitialize(
const challengeDeployment = await uupsProxyDeployAndInitialize(
l1Deployer,
await ethers.getContractFactory("Challenge"),
[
Expand Down
58 changes: 48 additions & 10 deletions scripts/hardhat/lib/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,41 @@
import { ethers } from "hardhat";
import { CanonicalStateChain } from "../../typechain-types";
import { CanonicalStateChain } from "../../../typechain-types";
import { Proxy } from "../../../typechain-types/contracts/universal";

export const proxyDeployAndInitialize = async (
signer: any,
implementationFactory: any,
args: any[],
) => {
// step 1: deploy implementation contract
const implementation = await implementationFactory.connect(signer).deploy();
await implementation.waitForDeployment();
const implementationAddress = await implementation.getAddress();

// step 2: deploy proxy contract
const proxyFactory = await ethers.getContractFactory(
"contracts/universal/Proxy.sol:Proxy",
signer,
);
const proxy: Proxy = (await proxyFactory
.connect(signer)
.deploy(signer.address)) as any;
await proxy.waitForDeployment();

await proxy.upgradeToAndCall(
implementationAddress,
implementation.interface.encodeFunctionData("initialize", args),
);

const proxyAddress = await proxy.getAddress();

return {
contract: await implementationFactory.attach(proxyAddress).connect(signer),
address: proxyAddress,
implementation,
implementationAddress,
};
};

/**
* Deploy a Proxy and contract and initialize it.
Expand All @@ -8,7 +44,7 @@ import { CanonicalStateChain } from "../../typechain-types";
* @param args The arguments to initialize on the contract.
* @returns The proxy and implementation contract.
*/
export const proxyDeployAndInitialize = async (
export const uupsProxyDeployAndInitialize = async (
signer: any,
implementationFactory: any,
args: any[],
Expand All @@ -19,7 +55,7 @@ export const proxyDeployAndInitialize = async (
const implementationAddress = await implementation.getAddress();

// step 2: deploy proxy contract
const proxyFactory: any = await ethers.getContractFactory("CoreProxy");
const proxyFactory = await ethers.getContractFactory("CoreProxy");
const contract = await proxyFactory
.connect(signer)
.deploy(
Expand All @@ -46,9 +82,11 @@ export const deployAndInitialize = async (
await contract.waitForDeployment();
await contract.initialize(...args);


return { contract: await factory.attach(contract.address), address: contract.address };
}
return {
contract: await factory.attach(contract.address),
address: contract.address,
};
};

export const createGenesisHeader = async (providerRPC: string) => {
const rpc = new ethers.JsonRpcProvider(providerRPC);
Expand All @@ -61,15 +99,15 @@ export const createGenesisHeader = async (providerRPC: string) => {

// calculate output root:
const versionHash = ethers.ZeroHash;
const stateRoot = latestBlock.stateRoot
const stateRoot = latestBlock.stateRoot;
const withdrawalRoot = ethers.ZeroHash;
const blockHash = latestBlock.hash
const blockHash = latestBlock.hash;

const outputRoot = ethers.keccak256(
ethers.solidityPacked(
["bytes32", "bytes32", "bytes32", "bytes32"],
[versionHash, stateRoot, withdrawalRoot, blockHash]
)
[versionHash, stateRoot, withdrawalRoot, blockHash],
),
);

// Step 3. Build genesis header from latest L2 block
Expand Down
4 changes: 2 additions & 2 deletions test/lib/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
CanonicalStateChain__factory,
CanonicalStateChain,
} from "../../typechain-types";
import { proxyDeployAndInitialize } from "../../scripts/hardhat/lib/deploy";
import { uupsProxyDeployAndInitialize } from "../../scripts/hardhat/lib/deploy";

type Header = CanonicalStateChain.HeaderStruct;

Expand All @@ -21,7 +21,7 @@ export const setupCanonicalStateChain = async (
celestiaPointers: [],
};

const deployed = await proxyDeployAndInitialize(
const deployed = await uupsProxyDeployAndInitialize(
signer,
await ethers.getContractFactory("CanonicalStateChain"),
[publisher, genesisHeader],
Expand Down
49 changes: 47 additions & 2 deletions test/tests/CrossChainTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,18 @@ import {
L1Block__factory,
} from "../../typechain-types";
import type { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers";
import { proxyDeployAndInitialize } from "../../scripts/hardhat/lib/deploy";
import {
proxyDeployAndInitialize,
uupsProxyDeployAndInitialize,
} from "../../scripts/hardhat/lib/deploy";
import {
initiateWithdraw,
getWithdrawalProofs,
sendMessageL2ToL1,
} from "../lib/bridge";
import { assert } from "console";
import { Proxy } from "../../typechain-types/contracts/universal";
import { Proxy__factory } from "../../typechain-types/factories/contracts/universal";

describe("Cross-chain interaction", function () {
// Networks
Expand Down Expand Up @@ -83,7 +88,7 @@ describe("Cross-chain interaction", function () {
console.log("CanonicalStateChain deployed");

// - Challenge
const challengeDeployment = await proxyDeployAndInitialize(
const challengeDeployment = await uupsProxyDeployAndInitialize(
l1Deployer,
await ethers.getContractFactory("Challenge"),
[
Expand All @@ -101,6 +106,7 @@ describe("Cross-chain interaction", function () {
[
await canonicalStateChain.getAddress(),
await challengeDeployment.address,
l1Deployer.address,
],
);
lightLinkPortal = lightLinkPortalDeployment.contract as LightLinkPortal;
Expand Down Expand Up @@ -228,6 +234,19 @@ describe("Cross-chain interaction", function () {
}); // describe("BridgeProofHelper")

describe("LightLinkPortal", function () {
it("Correct owner", async function () {
expect(await lightLinkPortal.connect(l1Deployer).owner()).to.equal(
l1Deployer.address,
);
});

it("Can Pause and Upause", async function () {
await lightLinkPortal.connect(l1Deployer).pause();
expect(await lightLinkPortal.connect(l1Deployer).paused()).to.be.true;
await lightLinkPortal.connect(l1Deployer).unpause();
expect(await lightLinkPortal.connect(l1Deployer).paused()).to.be.false;
});

it("Prove withdrawal", async function () {
// Initiate withdrawal from L2
const withdrawal = await initiateWithdraw(
Expand Down Expand Up @@ -478,6 +497,32 @@ describe("Cross-chain interaction", function () {
expect(finalizeTx, "Failed to call ping").to.emit(pingPong, "Pong");
});
}); // describe("L2CrossDomainMessenger")

describe("Proxy", async function () {
it("Upgrade LightLinkPortal", async function () {
// step 1: deploy new implementation
const newLightLinkPortalFactory =
await ethers.getContractFactory("LightLinkPortal");
const newLightLinkPortal = (await newLightLinkPortalFactory
.connect(l1Deployer)
.deploy()) as LightLinkPortal;

// step 2: upgrade proxy contract
const proxy = Proxy__factory.connect(
await lightLinkPortal.getAddress(),
l1Deployer,
);
const upgradeTx = await proxy
.connect(l1Deployer)
.upgradeTo(await newLightLinkPortal.getAddress());

const upgradeTxReceipt = await upgradeTx.wait();
expect(upgradeTxReceipt, "Failed to upgrade proxy").to.emit(
proxy,
"Upgraded",
);
});
});
});

const randomAddress = () => ethers.Wallet.createRandom().address;
Loading

0 comments on commit 7726b3c

Please sign in to comment.