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

2436 deployment scripts for lightclientarbitrum upgrade scripts lightclient #2449

1 change: 1 addition & 0 deletions .env.contracts.example
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export FEE_CONTRACT_ADDRESS=
# The etherscan API key is needed to verify contracts on etherscan.
export ETHERSCAN_API_KEY=
export SOLC_VERSION=
export ARBISCAN_API_KEY=

# foundry scripts
export DEPLOYER_PRIVATE_KEY= #include the 0x prefix
Expand Down
4 changes: 0 additions & 4 deletions .vscode/ltex.dictionary.en-US.txt

This file was deleted.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion contract-bindings/artifacts/LightClient_bytecode.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions contract-bindings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod erc1967_proxy;
pub mod fee_contract;
pub mod i_plonk_verifier;
pub mod light_client;
pub mod light_client_arbitrum;
pub mod light_client_mock;
pub mod light_client_state_update_vk;
pub mod light_client_state_update_vk_mock;
Expand Down
3,238 changes: 3,238 additions & 0 deletions contract-bindings/src/light_client_arbitrum.rs

Large diffs are not rendered by default.

263 changes: 263 additions & 0 deletions contracts/broadcast/LightClientArb.s.sol/421614/run-latest.json

Large diffs are not rendered by default.

53 changes: 53 additions & 0 deletions contracts/broadcast/PlonkVerifier.s.sol/421614/run-latest.json

Large diffs are not rendered by default.

85 changes: 85 additions & 0 deletions contracts/script/LightClientArb.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import { Script } from "forge-std/Script.sol";
import { LightClientArbitrum } from "../src/LightClientArbitrum.sol";
import { LightClient as LC } from "../src/LightClient.sol";
import { Upgrades } from "openzeppelin-foundry-upgrades/Upgrades.sol";

contract DeployLightClientArbitrum is Script {
// Deployment Errors
error SetPermissionedProverFailed();
error OwnerTransferFailed();
error RetentionPeriodIsNotSetCorrectly();
error InitialStateIsNotSetCorrectly();

function run(uint32 numInitValidators, uint32 stateHistoryRetentionPeriod, address owner)
public
returns (
address proxyAddress,
address implementationAddress,
LC.LightClientState memory lightClientState
)
{
address deployer;

string memory ledgerCommand = vm.envString("USE_HARDWARE_WALLET");
if (keccak256(bytes(ledgerCommand)) == keccak256(bytes("true"))) {
deployer = vm.envAddress("DEPLOYER_HARDWARE_WALLET_ADDRESS");
} else {
// get the deployer info from the environment
string memory seedPhrase = vm.envString("DEPLOYER_MNEMONIC");
uint32 seedPhraseOffset = uint32(vm.envUint("DEPLOYER_MNEMONIC_OFFSET"));
(deployer,) = deriveRememberKey(seedPhrase, seedPhraseOffset);
}

vm.startBroadcast(deployer);

string[] memory cmds = new string[](3);
cmds[0] = "diff-test";
cmds[1] = "mock-genesis";
cmds[2] = vm.toString(uint256(numInitValidators));

bytes memory result = vm.ffi(cmds);
(LC.LightClientState memory state, LC.StakeTableState memory stakeState) =
abi.decode(result, (LC.LightClientState, LC.StakeTableState));

proxyAddress = Upgrades.deployUUPSProxy(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this a proxy address? why cant we just deploy an implementation contract and then upgrade our existing proxy?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

opted for a deploy instead of an upgrade whilst dealing with the precompile issue. once this quick review is fine, i can continue with the upgrade steps

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

created a ticket for the upgrade script as the safe transaction service is not supported in arbitrum sepolia. this service is needed for proposing transactions to the safe multisig wallet, created another ticket #2457

"LightClientArbitrum.sol:LightClientArbitrum",
abi.encodeCall(
LC.initialize, (state, stakeState, stateHistoryRetentionPeriod, deployer)
)
);

LightClientArbitrum lightClientArbitrumProxy = LightClientArbitrum(proxyAddress);

// Currently, the light client is in prover mode so set the permissioned prover
address permissionedProver = vm.envAddress("PERMISSIONED_PROVER_ADDRESS");
lightClientArbitrumProxy.setPermissionedProver(permissionedProver);

// transfer ownership to the multisig
lightClientArbitrumProxy.transferOwnership(owner);

// verify post deployment details
if (lightClientArbitrumProxy.permissionedProver() != permissionedProver) {
revert SetPermissionedProverFailed();
}
if (lightClientArbitrumProxy.owner() != owner) revert OwnerTransferFailed();
if (lightClientArbitrumProxy.stateHistoryRetentionPeriod() != stateHistoryRetentionPeriod) {
revert RetentionPeriodIsNotSetCorrectly();
}
if (lightClientArbitrumProxy.stateHistoryFirstIndex() != 0) {
revert InitialStateIsNotSetCorrectly();
}
if (lightClientArbitrumProxy.getStateHistoryCount() != 0) {
revert InitialStateIsNotSetCorrectly();
}

// Get the implementation address
implementationAddress = Upgrades.getImplementationAddress(proxyAddress);

vm.stopBroadcast();

return (proxyAddress, implementationAddress, state);
}
}
2 changes: 1 addition & 1 deletion contracts/script/PlonkVerifier.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ pragma solidity ^0.8.20;
import { Script } from "forge-std/Script.sol";

import { Options, Upgrades } from "openzeppelin-foundry-upgrades/Upgrades.sol";

/// @notice Deploys an upgradeable Plonk Verifier Contract using the OpenZeppelin Upgrades plugin.
/// @dev The Upgrades library has a deployImplementation function which is used here

contract DeployPlonkVerifierScript is Script {
string public contractName = "PlonkVerifier.sol";

Expand Down
19 changes: 19 additions & 0 deletions contracts/script/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,3 +368,22 @@ This error occurs when build_info is set to true in the foundry.toml configurati
foundry profile is set to default when running commands like `just gen-bindings`.

Solution: `export FOUNDRY_PROFILE=default`

## Deploy LightClientArbitrum

Additional Pre-requisites:

- an API key from arbiscan to verify the contract.

```bash
source .env.contracts && \
forge clean && \
forge script contracts/script/LightClientArb.s.sol:DeployLightClientArbitrum $NUM_INIT_VALIDATORS $STATE_HISTORY_RETENTION_PERIOD $SAFE_MULTISIG_ADDRESS \
--sig 'run(uint32, uint32, address)' \
--ffi \
--rpc-url $RPC_URL \
--libraries contracts/src/libraries/PlonkVerifier.sol:PlonkVerifier:$PLONK_VERIFIER_ADDRESS \
--build-info true \
--verify --etherscan-api-key $ARBISCAN_API_KEY \
--broadcast
```
2 changes: 0 additions & 2 deletions contracts/src/LightClient.sol
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,6 @@ contract LightClient is Initializable, OwnableUpgradeable, UUPSUpgradeable {
finalizedState = _genesis;

stateHistoryRetentionPeriod = _stateHistoryRetentionPeriod;

updateStateHistory(uint64(currentBlockNumber()), uint64(block.timestamp), _genesis);
}

// === State Modifying APIs ===
Expand Down
23 changes: 10 additions & 13 deletions contracts/test/LightClient.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,9 @@ contract LightClient_StateUpdatesTest is LightClientCommonTest {
lc.newFinalizedState(states[i], proofs[i]);
}

// assert that the size of the state history is equal to the retention period
assertEq(lc.getStateHistoryCount(), numDays);

// the number of elements are equal to the max state history so the first index would
// be 0
assertEq(lc.stateHistoryFirstIndex(), 0);
Expand All @@ -708,14 +711,18 @@ contract LightClient_StateUpdatesTest is LightClientCommonTest {
vm.prank(permissionedProver);
vm.expectEmit(true, true, true, true);
emit LC.NewState(states[i].viewNum, states[i].blockHeight, states[i].blockCommRoot);
vm.warp(initialBlockTimestamp + ((i + 1) * 1 days)); // increase the timestamp for each
vm.warp((numDays + 3) * 1 days); // increase the timestamp
lc.newFinalizedState(states[i], proofs[i]);
i++;

// the duration between the updates are more than stateHistoryRetentionPeriod, so the first
// index should be one
assertEq(lc.stateHistoryFirstIndex(), 1);

// assert that the first state commitment is zero as it would have been deleted
(, uint256 blocktimestamp,,) = lc.stateHistoryCommitments(0);
assertEq(blocktimestamp, 0);

// continue updating the state
for (uint256 j = i; j < states.length; j++) {
vm.warp(initialBlockTimestamp + ((j + 1) * 1 days)); // increase the timestamp for each
Expand Down Expand Up @@ -822,8 +829,8 @@ contract LightClient_StateUpdatesTest is LightClientCommonTest {
}

function test_revertWhenBlockNumberTooHigh() public {
//assert that there is a state history
assertGt(lc.getStateHistoryCount(), 0);
// assert that there isn't a state history when the light client is first initialized
assertEq(lc.getStateHistoryCount(), 0);

vm.expectRevert(LC.InsufficientSnapshotHistory.selector);
lc.lagOverEscapeHatchThreshold(block.number + 10, 5); // No updates exist in history
Expand Down Expand Up @@ -1072,14 +1079,4 @@ contract LightClient_HotShotCommUpdatesTest is LightClientCommonTest {
assertEqBN254(hotShotBlockComm, blockComm);
assertEq(hotShotBlockHeight, blockHeight);
}

function test_revertWhenGetHotShotCommitmentInvalidHeight() public {
// Get the highest HotShot blockheight recorded
uint256 numCommitments = lc.getStateHistoryCount();
(,, uint64 blockHeight,) = lc.stateHistoryCommitments(numCommitments - 1);
// Expect revert when attempting to retrieve a block height higher than the highest one
// recorded
vm.expectRevert(LC.InvalidHotShotBlockForCommitmentCheck.selector);
lc.getHotShotCommitment(blockHeight + 1);
}
}
3 changes: 2 additions & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ build-docker-images:
scripts/build-docker-images-native

# generate rust bindings for contracts
REGEXP := "^LightClient$|^LightClientStateUpdateVK$|^FeeContract$|PlonkVerifier$|^ERC1967Proxy$|^LightClientMock$|^LightClientStateUpdateVKMock$|^PlonkVerifier2$|^PermissionedStakeTable$"
REGEXP := "^LightClient$|^LightClientArbitrum$|^LightClientStateUpdateVK$|^FeeContract$|PlonkVerifier$|^ERC1967Proxy$|^LightClientMock$|^LightClientStateUpdateVKMock$|^PlonkVerifier2$|^PermissionedStakeTable$"
gen-bindings:
forge bind --contracts ./contracts/src/ --crate-name contract-bindings --bindings-path contract-bindings --select "{{REGEXP}}" --overwrite --force

Expand All @@ -111,6 +111,7 @@ gen-bindings:
# date, without needed to recompile the contracts.
mkdir -p contract-bindings/artifacts
jq '.bytecode.object' < contracts/out/LightClient.sol/LightClient.json > contract-bindings/artifacts/LightClient_bytecode.json
jq '.bytecode.object' < contracts/out/LightClientArbitrum.sol/LightClientArbitrum.json > contract-bindings/artifacts/LightClientArbitrum_bytecode.json
jq '.bytecode.object' < contracts/out/LightClientMock.sol/LightClientMock.json > contract-bindings/artifacts/LightClientMock_bytecode.json

cargo fmt --all
Expand Down
Loading