-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Update L2ClaimTokens script * Update comments on L2ClaimTokens.s.sol * Add assertions to L2ClaimTokens.s.sol * Add demoClaim.sh script * Update comment * add publicity of Utils utils * Rearrange devnet files * Have 2 set of independent merkle trees for scripts and test
- Loading branch information
Showing
9 changed files
with
2,019 additions
and
30 deletions.
There are no files selected for viewing
File renamed without changes.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity 0.8.23; | ||
|
||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
import { Script, console2 } from "forge-std/Script.sol"; | ||
import { StdUtils } from "forge-std/StdUtils.sol"; | ||
import "script/Utils.sol"; | ||
|
||
/// @title DemoTransferFundsScript - Demo Transferring LSK to Claim contract | ||
/// @notice In Demo environment, after Claim contract is deployed, this script is used to send LSK tokens to Claim | ||
/// contract. | ||
contract DemoTransferFundsScript is Script { | ||
/// @notice Utils contract which provides functions to read and write JSON files containing L1 and L2 addresses. | ||
Utils internal utils; | ||
|
||
function setUp() public { | ||
utils = new Utils(); | ||
} | ||
|
||
/// @notice Transfer LSK Tokens to Claim contract | ||
function run() public { | ||
// Deployer's private key. Owner of the L2 Lisk token. PRIVATE_KEY is set in .env file. | ||
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); | ||
|
||
// read L2LiskToken address from l2addresses.json | ||
Utils.L2AddressesConfig memory l2AddressesConfig = utils.readL2AddressesFile(); | ||
IERC20 lsk = IERC20(l2AddressesConfig.L2LiskToken); | ||
|
||
vm.startBroadcast(deployerPrivateKey); | ||
lsk.transfer(l2AddressesConfig.L2ClaimContract, 10000 ether); | ||
vm.stopBroadcast(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,127 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity 0.8.23; | ||
|
||
import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; | ||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
import { Script, console2 } from "forge-std/Script.sol"; | ||
import { L2Claim } from "src/L2/L2Claim.sol"; | ||
import { stdJson } from "forge-std/StdJson.sol"; | ||
import { L2Claim, ED25519Signature, MultisigKeys } from "src/L2/L2Claim.sol"; | ||
import { Signature, MerkleTreeLeaf, MerkleLeaves } from "test/L2/L2Claim.t.sol"; | ||
import { MockERC20 } from "../../test/mock/MockERC20.sol"; | ||
import "script/Utils.sol"; | ||
|
||
/// @title L2ClaimTokensScript - L2 Claim Lisk tokens script | ||
/// @notice This contract is used to claim L2 Lisk tokens from the L2 Claim contract for a demonstration purpose. | ||
/// @notice This contract is used to claim L2 Lisk tokens from the L2 Claim contract for a demonstration purpose. This | ||
/// contract works independently without interacting with previously-deployed contracts and only works when `NETWORK` is | ||
/// set as `devnet`. | ||
contract L2ClaimTokensScript is Script { | ||
using stdJson for string; | ||
|
||
/// @notice Utils contract which provides functions to read and write JSON files containing L1 and L2 addresses. | ||
Utils utils; | ||
Utils internal utils; | ||
|
||
function setUp() public { | ||
utils = new Utils(); | ||
/// @notice LSK Token in L2. | ||
IERC20 internal lsk; | ||
|
||
/// @notice L2Claim Contract, with address pointing to Proxy. | ||
L2Claim internal l2Claim; | ||
|
||
/// @notice signatures.json in string format. | ||
string public signatureJson; | ||
|
||
/// @notice merkle-leaves.json in string format. | ||
string public merkleLeavesJson; | ||
|
||
/// @notice The contract address created by default mnemonic in Anvil/Ganache when nonce=0. | ||
address public constant destination = address(0x34A1D3fff3958843C43aD80F30b94c510645C316); | ||
|
||
/// @notice 1 Beddows in LSK Chain = 10 * 10 Beddows in L2 Chain | ||
uint256 public constant MULTIPLIER = 10 ** 10; | ||
|
||
function getSignature(uint256 _index) internal view returns (Signature memory) { | ||
return abi.decode(signatureJson.parseRaw(string(abi.encodePacked(".[", vm.toString(_index), "]"))), (Signature)); | ||
} | ||
|
||
/// @notice This function claims L2 Lisk tokens from the L2 Claim contract for a demonstration purpose. | ||
function run() public view { | ||
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); | ||
function getMerkleLeaves() internal view returns (MerkleLeaves memory) { | ||
return abi.decode(merkleLeavesJson.parseRaw("."), (MerkleLeaves)); | ||
} | ||
|
||
// print deployer address | ||
console2.log("Deployer address: %s", vm.addr(deployerPrivateKey)); | ||
function setUp() public { | ||
utils = new Utils(); | ||
|
||
// get L2Claim contract address | ||
Utils.L2AddressesConfig memory l2AddressesConfig = utils.readL2AddressesFile(); | ||
console2.log("L2 Claim contract address: %s", l2AddressesConfig.L2ClaimContract); | ||
lsk = IERC20(l2AddressesConfig.L2LiskToken); | ||
l2Claim = L2Claim(l2AddressesConfig.L2ClaimContract); | ||
|
||
// check L2Claim contract Lisk token balance | ||
L2Claim l2Claim = L2Claim(address(l2AddressesConfig.L2ClaimContract)); | ||
console2.log( | ||
"L2 Claim contract Lisk token balance before claim: %s", l2Claim.l2LiskToken().balanceOf(address(l2Claim)) | ||
); | ||
// Get Merkle Root from /devnet/merkle-root.json | ||
Utils.MerkleRoot memory merkleRoot = utils.readMerkleRootFile(); | ||
console2.log("MerkleRoot: %s", vm.toString(merkleRoot.merkleRoot)); | ||
|
||
// Read devnet Json files | ||
string memory rootPath = string.concat(vm.projectRoot(), "/script/data/devnet"); | ||
signatureJson = vm.readFile(string.concat(rootPath, "/signatures.json")); | ||
merkleLeavesJson = vm.readFile(string.concat(rootPath, "/merkle-leaves.json")); | ||
} | ||
|
||
// check deployer Lisk token balance | ||
/// @notice This function submit request to `claimRegularAccount` and `claimMultisigAccount` once to demonstrate | ||
/// claiming process of both regular account and multisig account | ||
function run() public { | ||
uint256 previousBalance = lsk.balanceOf(destination); | ||
console2.log("Destination LSK Balance before Claim:", previousBalance, "Beddows"); | ||
|
||
// Claiming Regular Account | ||
MerkleTreeLeaf memory regularAccountLeaf = getMerkleLeaves().leaves[0]; | ||
Signature memory regularAccountSignature = getSignature(0); | ||
console2.log( | ||
"Deployer's Lisk token balance before claim: %s", | ||
l2Claim.l2LiskToken().balanceOf(vm.addr(deployerPrivateKey)) | ||
"Claiming Regular Account: id=0, LSK address(hex)=%s, Balance (Old Beddows): %s", | ||
vm.toString(abi.encodePacked(bytes20(regularAccountLeaf.b32Address << 96))), | ||
regularAccountLeaf.balanceBeddows | ||
); | ||
l2Claim.claimRegularAccount( | ||
regularAccountLeaf.proof, | ||
regularAccountSignature.sigs[0].pubKey, | ||
regularAccountLeaf.balanceBeddows, | ||
destination, | ||
ED25519Signature(regularAccountSignature.sigs[0].r, regularAccountSignature.sigs[0].s) | ||
); | ||
assert(previousBalance + regularAccountLeaf.balanceBeddows * MULTIPLIER == lsk.balanceOf(destination)); | ||
console2.log("Destination LSK Balance After Regular Account Claim: %s Beddows", lsk.balanceOf(destination)); | ||
|
||
// Claiming Multisig Account | ||
uint256 multisigAccountIndex = 0; | ||
MerkleTreeLeaf memory multisigAccountLeaf = getMerkleLeaves().leaves[multisigAccountIndex]; | ||
|
||
// TODO: perform Claim Process for demonstration purpose | ||
// A non-hardcode way to get the first Multisig Account from Merkle Tree | ||
while (multisigAccountLeaf.numberOfSignatures == 0) { | ||
multisigAccountIndex++; | ||
multisigAccountLeaf = getMerkleLeaves().leaves[multisigAccountIndex]; | ||
} | ||
Signature memory multisigAccountSignature = getSignature(multisigAccountIndex); | ||
|
||
// check that L2Claim contract has less Lisk tokens than before | ||
console2.log( | ||
"L2 Claim contract Lisk token balance after claim: %s", l2Claim.l2LiskToken().balanceOf(address(l2Claim)) | ||
"Claiming Multisig Account: id=%s, LSK address(hex)=%s, Balance (Old Beddows): %s", | ||
multisigAccountIndex, | ||
vm.toString(abi.encodePacked(bytes20(multisigAccountLeaf.b32Address << 96))), | ||
multisigAccountLeaf.balanceBeddows | ||
); | ||
|
||
// check that deployer has 5 Lisk tokens | ||
console2.log( | ||
"Deployer's Lisk token balance after claim: %s", | ||
l2Claim.l2LiskToken().balanceOf(vm.addr(deployerPrivateKey)) | ||
// Gather just-right amount of signatures from signatures.json | ||
ED25519Signature[] memory ed25519Signatures = new ED25519Signature[](multisigAccountLeaf.numberOfSignatures); | ||
for (uint256 i; i < multisigAccountLeaf.numberOfSignatures; i++) { | ||
ed25519Signatures[i] = | ||
ED25519Signature(multisigAccountSignature.sigs[i].r, multisigAccountSignature.sigs[i].s); | ||
} | ||
|
||
previousBalance = lsk.balanceOf(destination); | ||
l2Claim.claimMultisigAccount( | ||
multisigAccountLeaf.proof, | ||
bytes20(multisigAccountLeaf.b32Address << 96), | ||
multisigAccountLeaf.balanceBeddows, | ||
MultisigKeys(multisigAccountLeaf.mandatoryKeys, multisigAccountLeaf.optionalKeys), | ||
destination, | ||
ed25519Signatures | ||
); | ||
assert(previousBalance + multisigAccountLeaf.balanceBeddows * MULTIPLIER == lsk.balanceOf(destination)); | ||
console2.log("Destination LSK Balance After Multisig Account Claim: %s Beddows", lsk.balanceOf(destination)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity 0.8.23; | ||
|
||
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | ||
import { Script, console2 } from "forge-std/Script.sol"; | ||
import { StdUtils } from "forge-std/StdUtils.sol"; | ||
import "script/Utils.sol"; | ||
|
||
/// @title L2DemoToken - Demo L2 LSK Token | ||
/// @notice In Demo environment, this contract will be used due to the lack of bridge. | ||
contract L2DemoToken is ERC20 { | ||
constructor(uint256 _totalSupply) ERC20("Demo Lisk Token", "dLSK") { | ||
_mint(msg.sender, _totalSupply); | ||
} | ||
} | ||
|
||
/// @title L2DemoTokenScript - Deploying Demo ERC20 as L2 LSK Token | ||
/// @notice In Demo environment, this script will be used to deploy L2 LSK Token and mint LSK to deployer. | ||
contract L2DemoTokenScript is Script { | ||
/// @notice Utils contract which provides functions to read and write JSON files containing L1 and L2 addresses. | ||
Utils internal utils; | ||
|
||
function setUp() public { | ||
utils = new Utils(); | ||
} | ||
|
||
function run() public { | ||
// Deployer's private key. Owner of the Demo L2 Lisk token. PRIVATE_KEY is set in .env file. | ||
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); | ||
|
||
console2.log("Deploying Demo Lisk token..."); | ||
|
||
vm.startBroadcast(deployerPrivateKey); | ||
ERC20 lsk = new L2DemoToken(10000 ether); | ||
vm.stopBroadcast(); | ||
|
||
assert(lsk.decimals() == 18); | ||
assert(lsk.totalSupply() == 10000 ether); | ||
|
||
console2.log("L2 Demo Lisk Token successfully deployed!"); | ||
console2.log("L2 Demo Lisk Token address: %s", address(lsk)); | ||
|
||
// write L2LiskToken address to l2addresses.json | ||
Utils.L2AddressesConfig memory l2AddressesConfig; | ||
l2AddressesConfig.L2LiskToken = address(lsk); | ||
utils.writeL2AddressesFile(l2AddressesConfig); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#!/usr/bin/env bash | ||
|
||
echo "*** This script should only run at DEVNET ***" | ||
|
||
echo "Instructing the shell to exit immediately if any command returns a non-zero exit status..." | ||
set -e | ||
echo "Done." | ||
|
||
echo "Navigating to the root directory of the project..." | ||
cd ../../ | ||
echo "Done." | ||
|
||
echo "Setting environment variables..." | ||
source .env | ||
echo "Done." | ||
|
||
if [ "$NETWORK" != "devnet" ] | ||
then | ||
echo "This script can only be running at devnet, please change your NETWORK at .env" | ||
exit | ||
fi | ||
|
||
echo "Removing files inside deployment directory if they exists..." | ||
rm -rf deployment/devnet | ||
echo "Done." | ||
|
||
echo "Creating devnet directory inside deployment directory..." | ||
mkdir deployment/devnet | ||
echo "Done." | ||
|
||
echo "Deploying Demo L2LiskToken smart contract..." | ||
forge script --rpc-url="$L2_RPC_URL" --broadcast -vvvv script/example/L2DemoToken.s.sol:L2DemoTokenScript | ||
echo "Done." | ||
|
||
echo "Deploying L2Claim smart contract..." | ||
forge script --rpc-url="$L2_RPC_URL" --broadcast -vvvv script/L2Claim.s.sol:L2ClaimScript | ||
echo "Done." | ||
|
||
echo "Transferring funds to L2Claim smart contract..." | ||
forge script --rpc-url="$L2_RPC_URL" --broadcast -vvvv script/example/DemoTransferFunds.s.sol:DemoTransferFundsScript | ||
echo "Done." | ||
|
||
echo "Submitting Claim..." | ||
forge script --rpc-url="$L2_RPC_URL" --broadcast -vvvv script/example/L2ClaimTokens.s.sol:L2ClaimTokensScript | ||
echo "Done." | ||
|
||
echo "Completed." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.