Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e457950
add configurations for sonic and sonicTestnet and deploy GS Token to …
0xDanr Apr 2, 2025
5493429
deploy GS token to Sonic mainnet
0xDanr Apr 2, 2025
7264e37
update LZ peers script to set enforced options upon setting peer
0xDanr Apr 3, 2025
5bd4d46
add sonic multisig as timelock proposer and executor, deploy Timelock…
0xDanr Apr 3, 2025
c586672
deploy TimelockController to sonic and update README
0xDanr Apr 3, 2025
1970b9e
transfer GS token ownership to timelock-controler in sonic
0xDanr Apr 3, 2025
49af05f
only set enforced options on chains where it has not been set
0xDanr Apr 3, 2025
a7d6ea9
fix lastId comment
0xDanr Apr 3, 2025
afc8002
create 08-update-timelock-set-lzpeers.ts files to set lzPeers when us…
0xDanr Apr 3, 2025
77a2bd6
connect to sender when calling quoteSend in bridge task
0xDanr Apr 3, 2025
7ab56b6
create lz-config and lz-set-config tasks to set tasks for LZ bridging
0xDanr Apr 8, 2025
10e28a5
make isMainnet() and sleep() local functions in lz-set-config
0xDanr Apr 8, 2025
ea612f2
add task to set delegate in GS Token's OAPP
0xDanr Apr 8, 2025
4b22dd7
set test configurations
0xDanr Apr 9, 2025
2163bb8
update LZ DVNs
0xDanr Apr 9, 2025
e8b8803
enable passing of lastid to lz-set-config task
0xDanr Apr 9, 2025
185cbbd
add exec param to lz-set-config, fix bugs
0xDanr Apr 11, 2025
e166289
print out salt
0xDanr Apr 11, 2025
1d725f4
add instructions on how to set DVNs in README file
0xDanr Apr 13, 2025
0d8a56f
add correct comments to lz-set-config and lz-get-config, and add noti…
0xDanr Apr 13, 2025
ab90ff2
set sonic timelockController minDelay to 1 day
0xDanr Apr 13, 2025
26a42a9
update bridge task
0xDanr Apr 14, 2025
e335da4
log confirmations in timelock delay update
0xDanr Apr 14, 2025
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
30 changes: 27 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,30 @@ GammaSwap token used to secure liquidation and rebalancing logic in exchange for
# Deployment Steps

1. Run 01-deploy-gs-token.ts in every chain
2. Set addresses of GS Token deployed in every chain in helper-hardhat-config.ts in erc20Tokens section in networkConfigInfo
3. Run 02-deploy-set-lzpeers.ts to connect every token to every token in every chain where it is deployed
4. Run 03-deploy-timelock-controller.ts to transfer ownership of the GS Token to the timelock controller
(No need to set up mintGSTokenTo or initialGSTokenAmt in helper-hardhat-config.ts unless it's first deployment)
2. Update helper-hardhat-config.ts
Set lzEid and lzEndpoing for new chain from LayerZero's docs
Set addresses of GS Token deployed in every chain in helper-hardhat-config.ts in erc20Tokens section in networkConfigInfo
Add the chain name to developmentLzPeers and productionLzPeers in helper-hardhat-config.ts
Add gnosis multisig address as timelock proposer and executor
3. Run 02-deploy-set-lzpeers.ts to connect every token to every token in every chain where it is deployed.
If it's the first deployment, it must be run for every chain.
4. Run 03-deploy-timelock-controller.ts to deploy timelockController for new GS token chain (use a short minDelay)
5. Run 05-transfer-gs-ownership.ts to transfer GS Token ownership to timelock-controller
6. Run 07-update-enforced-options.ts on all non-new chains to set the enforced options from all peers to new peer.
7. Run 08-deploy-timelock-set-lzpeers.ts to set LZ peers of non-new chains to new peer
8. Check that network has correct configurations using task lz-config.ts. Make sure DVNs and Libs are not dead.
If they're not set or are dead then set the DVNs, SendLib, ReceiveLib, and Executor following the steps from section below.
8. Run 06-update-timelock-delay.ts, to set the timelock on the new chain to 1 day (set minDelay to 1 day in seconds)

# How to set DVNs, SendLib, ReceiveLib, and Executors

*The delegate of GS token has to also be the timelockController. Otherwise the timelockController
won't be able to set the configurations. Set the delegate using task lz-set-delegate.ts.

1. Fill in LZ configurations in helper-hardhat-config.ts.
Get DVNs from https://docs.layerzero.network/v2/deployments/dvn-addresses
Get Send/Rec/Exec Libs from https://docs.layerzero.network/v2/deployments/deployed-contracts
2. Make sure the DVN count, confirmations, and providers from send to receive chain match.
3. Run task lz-set-config.ts
4. Check configurations were set correctly (i.e. they match on both send and receive chain) using task lz-config.ts
16 changes: 16 additions & 0 deletions deploy/02-deploy-set-lzpeers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { DeployFunction } from "hardhat-deploy/types"
import { isMainnet } from "../helper-functions"
import { ethers } from "hardhat";
import { networkConfig, developmentLzPeers, productionLzPeers } from "../helper-hardhat-config";
import { Options } from "@layerzerolabs/lz-v2-utilities";

const deploySetLZPeers: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
// @ts-ignore
Expand Down Expand Up @@ -37,6 +38,21 @@ const deploySetLZPeers: DeployFunction = async function (hre: HardhatRuntimeEnvi
const tx = await (await gsContract.connect(_deployer).setPeer(lzEid, _gsAddr)).wait(confirmations);
if(tx && tx.transactionHash) {
log("GS in",network.name,"set peer for",peerNetwork,"in",tx.transactionHash)

const op = await gsContract.enforcedOptions(lzEid, 1)
log("op[",lzEid,"] before >> ", op)

const options = Options.newOptions().addExecutorLzReceiveOption(200000, 0).toHex().toString()
const enforcedOptionParams = [{
eid: lzEid,
msgType: 1, // 1: SEND, 2: SEND_AND_CALL
options: options
}];

const _tx = await (await gsContract.connect(_deployer).setEnforcedOptions(enforcedOptionParams)).wait(confirmations);
if(_tx && _tx.transactionHash) {
log("GS in",network.name,"set options",options,"for",peerNetwork,"in",_tx.transactionHash)
}
}
} else {
log("GS already has peer at",peerNetwork)
Expand Down
1 change: 1 addition & 0 deletions deploy/05-transfer-gs-ownership.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const deployTransferGSOwnership: DeployFunction = async function (hre: HardhatRu
const iface = new hre.ethers.utils.Interface(abi);

const data = iface.encodeFunctionData("acceptOwnership", []);
log("data:", data.toString())

const timelockControllerContract = await ethers.getContractAt("TimelockController", timelockController.address);

Expand Down
1 change: 1 addition & 0 deletions deploy/06-update-timelock-delay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const updateMinDelay: DeployFunction = async function (hre: HardhatRuntimeEnviro
log(`deployer: ${deployer}`)

const confirmations = networkConfig[network.name].longBlockConfirmations;
log(`confirmations: ${confirmations}`)

const _deployer = await hre.ethers.getSigner(deployer);

Expand Down
40 changes: 27 additions & 13 deletions deploy/07-update-enforced-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,32 @@ const updateEnforcedOptions: DeployFunction = async function (hre: HardhatRuntim
const lzEid = Number(cfg.lzEid || "0");
const op = await gsContract.enforcedOptions(lzEid, 1)
log("op[",lzEid,"] before >> ", op)

const enforcedOptionParams = [{
eid: lzEid,
msgType: 1, // 1: SEND, 2: SEND_AND_CALL
options: options
}];

const data = gsContract.interface.encodeFunctionData('setEnforcedOptions', [enforcedOptionParams]);
log("data >>", data)
payloads.push(data)
targets.push(gs.address)
values.push(0)
if(op == "0x") {
const enforcedOptionParams = [{
eid: lzEid,
msgType: 1, // 1: SEND, 2: SEND_AND_CALL
options: options
}];

const data = gsContract.interface.encodeFunctionData('setEnforcedOptions', [enforcedOptionParams]);
log("data >>", data)
payloads.push(data)
targets.push(gs.address)
values.push(0)
} else {
log("enforced options already set for",peerNetwork,"lzEid:",lzEid)
}
}
}
log("payloads >> ", payloads)
log("targets >> ", targets)
log("values >> ", values)

if(payloads.length == 0) {
log("enforced options have already been set for all chains")
return
}

const timelockControllerContract = await ethers.getContractAt("TimelockController", timelockController.address);

const currMinDelay = await timelockControllerContract.getMinDelay();
Expand All @@ -71,6 +79,12 @@ const updateEnforcedOptions: DeployFunction = async function (hre: HardhatRuntim
const lastId = events.length > 0 ? events[events.length - 1].args.id : hre.ethers.constants.HashZero;
log("lastId:", lastId)

log("==================scheduleBatch parameters==================")
log("payloads:", payloads)
log("targets :", targets)
log("values :", values)
log("lastId :", lastId)
log("============================================================")
let tx = await (await timelockControllerContract.connect(_deployer).scheduleBatch(targets, values, payloads, lastId, hre.ethers.constants.HashZero, currMinDelay)).wait(confirmations);
if(tx && tx.transactionHash) {
log("scheduled setEnforcedOptions(struct) at", tx.transactionHash)
Expand All @@ -94,7 +108,7 @@ const updateEnforcedOptions: DeployFunction = async function (hre: HardhatRuntim
const cfg = networkConfig[peerNetwork]
const lzEid = Number(cfg.lzEid || "0");
const op = await gsContract.enforcedOptions(lzEid, 1)
log("op[", lzEid, " after >> ", op)
log("op[", lzEid, "] after >> ", op)
}
}
log("----------------------------------------------------")
Expand Down
119 changes: 119 additions & 0 deletions deploy/08-update-timelock-set-lzpeers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { HardhatRuntimeEnvironment } from "hardhat/types"
import { DeployFunction } from "hardhat-deploy/types"
import { isMainnet, sleep } from "../helper-functions";
import { developmentLzPeers, networkConfig, productionLzPeers } from "../helper-hardhat-config";
import { ethers } from "hardhat";
import { TimelockController, GS } from "../typechain-types";

const updateEnforcedOptions: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { getNamedAccounts, deployments, network } = hre
const { log, get } = deployments
const { deployer } = await getNamedAccounts()
log(`deployer: ${deployer}`)

const confirmations = networkConfig[network.name].longBlockConfirmations;

const _deployer = await hre.ethers.getSigner(deployer);

const timelockController = await get("TimelockController");
log(`timelockController: ${timelockController.address}`)

const gs = await get("GS");
log(`gs: ${gs.address}`)

const gsContract = (await ethers.getContractAt('GS', gs.address)) as unknown as GS;

const lzPeers = isMainnet(hre) ? productionLzPeers : developmentLzPeers

const payloads = []
const targets = []
const values = []
for(let i = 0; i < lzPeers.length; i++) {
const peerNetwork = lzPeers[i]
if (network.name != peerNetwork) {
const cfg = networkConfig[peerNetwork]
const lzEid = Number(cfg.lzEid || "0");
const gsAddr = cfg.erc20Tokens?.gs || ""
log("Setting Peer for network",peerNetwork," >> lzEid:", lzEid," gs:",gsAddr)
if(lzEid > 0 && ethers.utils.isAddress(gsAddr)) {
const _gsAddr = ethers.utils.zeroPad(gsAddr, 32)
const hasPeer = await gsContract.isPeer(lzEid, _gsAddr);
if(!hasPeer) {
log("set peer")
const _gsAddrStr = ethers.utils.hexlify(_gsAddr)
log("_gsAddr:",_gsAddrStr);
const data = gsContract.interface.encodeFunctionData('setPeer', [lzEid, _gsAddrStr]);
payloads.push(data)
targets.push(gs.address)
values.push(0)
} else {
log("GS already has peer at", peerNetwork)
}
} else {
log("Peer not set for", peerNetwork)
}
}
}
log("payloads >> ", payloads)
log("targets >> ", targets)
log("values >> ", values)

if(payloads.length == 0) {
log("Peers have already been set for all chains")
return
}

const timelockControllerContract = await ethers.getContractAt("TimelockController", timelockController.address);

const currMinDelay = await timelockControllerContract.getMinDelay();
log(`currMinDelay: ${currMinDelay}`)

const eventName = "CallScheduled";
const latestBlock = await hre.ethers.provider.getBlockNumber();
log("latestBlock:", latestBlock)

// Fetch events
const events = await timelockControllerContract.queryFilter(timelockControllerContract.filters[eventName](), 0, latestBlock);

const lastId = events.length > 0 ? events[events.length - 1].args.id : hre.ethers.constants.HashZero;
log("lastId:", lastId)

log("==================scheduleBatch parameters==================")
log("payloads:", payloads)
log("targets :", targets)
log("values :", values)
log("lastId :", lastId)
log("============================================================")
let tx = await (await timelockControllerContract.connect(_deployer).scheduleBatch(targets, values, payloads, lastId, hre.ethers.constants.HashZero, currMinDelay)).wait(confirmations);
if(tx && tx.transactionHash) {
log("scheduled setPeer(lzEid,peerAddr) at", tx.transactionHash)
} else {
log("ERROR scheduling setPeer(lzEid,peerAddr)")
return
}

const waitSeconds = Number(currMinDelay) + 20
log("waitSeconds:",waitSeconds)
await sleep(waitSeconds * 1000)

tx = await (await timelockControllerContract.connect(_deployer).executeBatch(targets, values, payloads, lastId, hre.ethers.constants.HashZero)).wait(confirmations);
if(tx && tx.transactionHash) {
log("execute setPeer(lzEid,peerAddr) at", tx.transactionHash)
}

for(let i = 0; i < lzPeers.length; i++) {
const peerNetwork = lzPeers[i]
if (network.name != peerNetwork) {
const cfg = networkConfig[peerNetwork]
const lzEid = Number(cfg.lzEid || "0");
const gsAddr = cfg.erc20Tokens?.gs || ""
const _gsAddr = ethers.utils.zeroPad(gsAddr, 32)
const hasPeer = await gsContract.isPeer(lzEid, _gsAddr);
log("Checking if Peer for network",peerNetwork," lzEid:", lzEid," gs:",gsAddr," is set?",hasPeer)
}
}
log("----------------------------------------------------")
}

export default updateEnforcedOptions
updateEnforcedOptions.tags = ["all-timelock", "timelock-lz-peers"]
1 change: 1 addition & 0 deletions deployments/sonic/.chainId
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
146
143 changes: 143 additions & 0 deletions deployments/sonic/GS.json

Large diffs are not rendered by default.

Loading
Loading