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

feat: deploy to Linea #18

Open
wants to merge 7 commits into
base: feat/membership
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
52 changes: 24 additions & 28 deletions .gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
WakuRlnV2Test:test__IdCommitmentToMetadata__DoesntExist() (gas: 27547)
WakuRlnV2Test:test__InsertionNormalOrder(uint32) (runs: 1005, μ: 1284765, ~: 577056)
WakuRlnV2Test:test__InvalidPaginationQuery__EndIndexGTnextCommitmentIndex() (gas: 18290)
WakuRlnV2Test:test__InvalidPaginationQuery__StartIndexGTEndIndex() (gas: 16181)
WakuRlnV2Test:test__InvalidRegistration__DuplicateIdCommitment() (gas: 322752)
WakuRlnV2Test:test__InvalidRegistration__FullTree() (gas: 239810)
WakuRlnV2Test:test__InvalidRegistration__InvalidIdCommitment__LargerThanField() (gas: 36509)
WakuRlnV2Test:test__InvalidRegistration__InvalidIdCommitment__Zero() (gas: 35220)
WakuRlnV2Test:test__InvalidRegistration__InvalidUserMessageLimit__MinMax() (gas: 63679)
WakuRlnV2Test:test__InvalidTokenAmount(uint256,uint32) (runs: 1004, μ: 207863, ~: 207863)
WakuRlnV2Test:test__LinearPriceCalculation(uint32) (runs: 1015, μ: 26049, ~: 26049)
WakuRlnV2Test:test__RegistrationWhenMaxRateLimitIsReached() (gas: 638698)
WakuRlnV2Test:test__RegistrationWhenMaxRateLimitIsReachedAndMultipleExpiredMembersAvailable() (gas: 906196)
WakuRlnV2Test:test__RegistrationWhenMaxRateLimitIsReachedAndSingleExpiredMemberAvailable() (gas: 461585)
WakuRlnV2Test:test__RegistrationWhenMaxRateLimitReachedAndMultipleExpiredMembersAvailableWithoutEnoughRateLimit() (gas: 869622)
WakuRlnV2Test:test__RemoveAllExpiredMemberships(uint32) (runs: 1005, μ: 7359251, ~: 1585880)
WakuRlnV2Test:test__RemoveExpiredMemberships(uint32) (runs: 1003, μ: 1248285, ~: 1248286)
WakuRlnV2Test:test__Upgrade() (gas: 7482875)
WakuRlnV2Test:test__ValidPaginationQuery(uint32) (runs: 1006, μ: 227626, ~: 52991)
WakuRlnV2Test:test__ValidPaginationQuery__OneElement() (gas: 319333)
WakuRlnV2Test:test__ValidRegistration(uint32) (runs: 1003, μ: 325571, ~: 325571)
WakuRlnV2Test:test__ValidRegistrationExpiry(uint32) (runs: 1003, μ: 1456074, ~: 1456074)
WakuRlnV2Test:test__ValidRegistrationExtend(uint32) (runs: 1003, μ: 1276008, ~: 1276008)
WakuRlnV2Test:test__ValidRegistrationExtendSingleMembership(uint32) (runs: 1003, μ: 314390, ~: 314390)
WakuRlnV2Test:test__ValidRegistrationWithEraseList() (gas: 1601871)
WakuRlnV2Test:test__ValidRegistration__kats() (gas: 295683)
WakuRlnV2Test:test__WithdrawToken(uint32) (runs: 1003, μ: 301025, ~: 301027)
WakuRlnV2Test:test__indexReuse_eraseMemberships(uint32) (runs: 1005, μ: 2702739, ~: 1165772)
WakuRlnV2Test:test__IdCommitmentToMetadata__DoesntExist() (gas: 23299)
WakuRlnV2Test:test__InvalidPaginationQuery__EndIndexGTnextCommitmentIndex() (gas: 18307)
WakuRlnV2Test:test__InvalidPaginationQuery__StartIndexGTEndIndex() (gas: 16131)
WakuRlnV2Test:test__InvalidRegistration__DuplicateIdCommitment() (gas: 272654)
WakuRlnV2Test:test__InvalidRegistration__FullTree() (gas: 190004)
WakuRlnV2Test:test__InvalidRegistration__InvalidIdCommitment__LargerThanField() (gas: 36492)
WakuRlnV2Test:test__InvalidRegistration__InvalidIdCommitment__Zero() (gas: 35192)
WakuRlnV2Test:test__InvalidRegistration__InvalidUserMessageLimit__MinMax() (gas: 55026)
WakuRlnV2Test:test__InvalidTokenAmount(uint256,uint32) (runs: 1006, μ: 158053, ~: 158053)
WakuRlnV2Test:test__LinearPriceCalculation(uint32) (runs: 1015, μ: 26026, ~: 26026)
WakuRlnV2Test:test__RegistrationWhenMaxRateLimitIsReached() (gas: 527384)
WakuRlnV2Test:test__RemoveAllExpiredMemberships(uint32) (runs: 1004, μ: 3577547, ~: 653139)
WakuRlnV2Test:test__RemoveExpiredMemberships(uint32) (runs: 1003, μ: 1044941, ~: 1044943)
WakuRlnV2Test:test__Upgrade() (gas: 6932864)
WakuRlnV2Test:test__ValidPaginationQuery(uint32) (runs: 1005, μ: 227459, ~: 52991)
WakuRlnV2Test:test__ValidPaginationQuery__OneElement() (gas: 269528)
WakuRlnV2Test:test__ValidRegistration(uint32) (runs: 1003, μ: 275279, ~: 275279)
WakuRlnV2Test:test__ValidRegistrationExpiry(uint32) (runs: 1003, μ: 256301, ~: 256301)
WakuRlnV2Test:test__ValidRegistrationExtend(uint32) (runs: 1003, μ: 474309, ~: 474309)
WakuRlnV2Test:test__ValidRegistrationExtendSingleMembership(uint32) (runs: 1003, μ: 263787, ~: 263787)
WakuRlnV2Test:test__ValidRegistrationWithEraseList() (gas: 1380002)
WakuRlnV2Test:test__ValidRegistration__kats() (gas: 245878)
WakuRlnV2Test:test__WithdrawToken(uint32) (runs: 1003, μ: 260362, ~: 260364)
WakuRlnV2Test:test__indexReuse_eraseMemberships(uint32) (runs: 1004, μ: 2377343, ~: 975838)
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@
[submodule "lib/openzeppelin-contracts-upgradeable"]
path = lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
[submodule "lib/foundry-devops"]
path = lib/foundry-devops
url = https://github.com/Cyfrin/foundry-devops
1 change: 1 addition & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
solc = "0.8.24"
src = "src"
test = "test"
fs_permissions = [{ access = "read", path = "./broadcast" }]

[fuzz]
max_test_rejects = 128_000
Expand Down
1 change: 1 addition & 0 deletions lib/foundry-devops
Submodule foundry-devops added at 47393d
10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,13 @@
"adorno": "pnpm prettier:write && forge fmt && forge snapshot && pnpm gas-report",
"deploy:sepolia": "./envCheck.sh && FOUNDRY_PROFILE=sepolia forge script --chain sepolia script/Deploy.s.sol:Deploy --rpc-url $RPC_URL --broadcast --verify -vv --account $ACCOUNT --legacy --sender $ETH_FROM",
"deploy:cardona": "export RPC_URL=https://rpc.cardona.zkevm-rpc.com && ./envCheck.sh && FOUNDRY_PROFILE=cardona forge script --chain 2442 script/Deploy.s.sol:Deploy --rpc-url $RPC_URL --broadcast --verify -vv --account $ACCOUNT --legacy --sender $ETH_FROM",
"deploy:linea_sepolia": "export RPC_URL=https://rpc.sepolia.linea.build && ./envCheck.sh && FOUNDRY_PROFILE=linea_sepolia forge script --chain 59141 script/Deploy.s.sol:Deploy --rpc-url $RPC_URL --broadcast --verify -vv --account $ACCOUNT --legacy --sender $ETH_FROM",
"deploy:localhost": "./envCheck.sh && forge script script/Deploy.s.sol:Deploy --rpc-url $RPC_URL --broadcast -vv --account $ACCOUNT --sender $ETH_FROM"
"deploy:localhost:price_calculator": "./envCheck.sh && forge script script/Deploy.s.sol:DeployPriceCalculator --rpc-url $RPC_URL --broadcast -vv --sender $ETH_FROM --account $ACCOUNT",
"deploy:localhost:wakurln_impl_v2": "./envCheck.sh && forge script script/Deploy.s.sol:DeployWakuRlnV2 --rpc-url $RPC_URL --broadcast -vv --sender $ETH_FROM --account $ACCOUNT",
"deploy:localhost:proxy": "./envCheck.sh && forge script script/Deploy.s.sol:DeployProxy --rpc-url $RPC_URL --broadcast -vv --sender $ETH_FROM --account $ACCOUNT",
"deploy:localhost": "npm run deploy:localhost:price_calculator && npm run deploy:localhost:wakurln_impl_v2 && npm run deploy:localhost:proxy",
"deploy:linea_sepolia:price_calculator": "export RPC_URL=https://rpc.sepolia.linea.build && ./envCheck.sh && FOUNDRY_PROFILE=linea_sepolia forge script --chain 59141 script/Deploy.s.sol:DeployPriceCalculator --rpc-url $RPC_URL --broadcast --verify -vv --account $ACCOUNT --legacy --sender $ETH_FROM",
"deploy:linea_sepolia:wakurln_impl_v2": "export RPC_URL=https://rpc.sepolia.linea.build && ./envCheck.sh && FOUNDRY_PROFILE=linea_sepolia forge script --chain 59141 script/Deploy.s.sol:DeployWakuRlnV2 --rpc-url $RPC_URL --broadcast --verify -vv --account $ACCOUNT --legacy --sender $ETH_FROM",
"deploy:linea_sepolia:proxy": "export RPC_URL=https://rpc.sepolia.linea.build && ./envCheck.sh && FOUNDRY_PROFILE=linea_sepolia forge script --chain 59141 script/Deploy.s.sol:DeployProxy --rpc-url $RPC_URL --broadcast --verify -vv --account $ACCOUNT --legacy --sender $ETH_FROM",
"deploy:linea_sepolia": "npm run deploy:linea_sepolia:price_calculator && npm run deploy:linea_sepolia:wakurln_impl_v2 && npm run deploy:linea_sepolia:proxy"
}
}
78 changes: 68 additions & 10 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,25 @@
pragma solidity >=0.8.19 <=0.9.0;

import { WakuRlnV2 } from "../src/WakuRlnV2.sol";
import { IPriceCalculator } from "../src/IPriceCalculator.sol";
import { LinearPriceCalculator } from "../src/LinearPriceCalculator.sol";
import { PoseidonT3 } from "poseidon-solidity/PoseidonT3.sol";
import { LazyIMT } from "@zk-kit/imt.sol/LazyIMT.sol";
import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

Check warning on line 10 in script/Deploy.s.sol

View workflow job for this annotation

GitHub Actions / lint

imported name UUPSUpgradeable is not used

import { DevOpsTools } from "lib/foundry-devops/src/DevOpsTools.sol";
import { BaseScript } from "./Base.s.sol";
import "forge-std/console.sol";

Check warning on line 13 in script/Deploy.s.sol

View workflow job for this annotation

GitHub Actions / lint

global import of path forge-std/console.sol is not allowed. Specify names to import individually or bind all exports of the module into a name (import "path" as Name)

contract Deploy is BaseScript {
function run() public broadcast returns (WakuRlnV2 w, address impl) {
contract DeployPriceCalculator is BaseScript {
function run() public broadcast returns (address) {
address _token = _getTokenAddress();
return deploy(_token);
return address(deploy(_token));
}

function deploy(address _token) public returns (WakuRlnV2 w, address impl) {
address priceCalcAddr = address(new LinearPriceCalculator(_token, 0.05 ether));
impl = address(new WakuRlnV2());
bytes memory data = abi.encodeCall(WakuRlnV2.initialize, (priceCalcAddr, 160_000, 20, 600, 180 days, 30 days));
address proxy = address(new ERC1967Proxy(impl, data));
w = WakuRlnV2(proxy);
function deploy(address _token) public returns (IPriceCalculator) {
LinearPriceCalculator priceCalculator = new LinearPriceCalculator(_token, 0.05 ether);
return IPriceCalculator(priceCalculator);
}

function _getTokenAddress() internal view returns (address) {
Expand All @@ -37,15 +36,74 @@
}
}

contract DeployWakuRlnV2 is BaseScript {
function run() public broadcast returns (address) {
return address(deploy());
}

function deploy() public returns (WakuRlnV2) {
return new WakuRlnV2();
}
}

contract DeployProxy is BaseScript {
uint32 public constant MAX_TOTAL_RATELIMIT_PER_EPOCH = 160_000;
uint32 public constant MIN_RATELIMIT_PER_MEMBERSHIP = 20;
uint32 public constant MAX_RATELIMIT_PER_MEMBERSHIP = 600;
uint32 public constant EXPIRATION_TERM = 180 days;
uint32 public constant GRACE_PERIOD = 30 days;

function run() public broadcast returns (address) {
address priceCalcAddr;
address wakuRlnV2ImplAddr;

try vm.envAddress("PRICE_CALCULATOR_ADDRESS") returns (address envPriceCalcAddress) {
console.log("Loading price calculator address from environment variable");
priceCalcAddr = envPriceCalcAddress;
} catch {
console.log("Loading price calculator address from broadcast directory");
priceCalcAddr = DevOpsTools.get_most_recent_deployment("LinearPriceCalculator", block.chainid);
}

try vm.envAddress("WAKURLNV2_ADDRESS") returns (address envWakuRlnV2ImplAddr) {
console.log("Loading WakuRlnV2 address from environment variable");
wakuRlnV2ImplAddr = envWakuRlnV2ImplAddr;
} catch {
console.log("Loading WakuRlnV2 address from broadcast directory");
wakuRlnV2ImplAddr = DevOpsTools.get_most_recent_deployment("WakuRlnV2", block.chainid);
}

console.log("Using price calculator address: %s", priceCalcAddr);
console.log("Using WakuRLNV2 address: %s", wakuRlnV2ImplAddr);

return address(deploy(priceCalcAddr, wakuRlnV2ImplAddr));
}

function deploy(address _priceCalcAddr, address _wakuRlnV2ImplAddr) public returns (ERC1967Proxy) {
bytes memory data = abi.encodeCall(
WakuRlnV2.initialize,
(
_priceCalcAddr,
MAX_TOTAL_RATELIMIT_PER_EPOCH,
MIN_RATELIMIT_PER_MEMBERSHIP,
MAX_RATELIMIT_PER_MEMBERSHIP,
EXPIRATION_TERM,
GRACE_PERIOD
)
);
return new ERC1967Proxy(_wakuRlnV2ImplAddr, data);
}
}

contract DeployLibs is BaseScript {
function run() public broadcast returns (address poseidonT3, address lazyImt) {
bytes memory poseidonT3Bytecode = type(PoseidonT3).creationCode;
assembly {

Check warning on line 101 in script/Deploy.s.sol

View workflow job for this annotation

GitHub Actions / lint

Avoid to use inline assembly. It is acceptable only in rare cases
poseidonT3 := create(0, add(poseidonT3Bytecode, 0x20), mload(poseidonT3Bytecode))
}

bytes memory lazyImtBytecode = type(LazyIMT).creationCode;
assembly {

Check warning on line 106 in script/Deploy.s.sol

View workflow job for this annotation

GitHub Actions / lint

Avoid to use inline assembly. It is acceptable only in rare cases
lazyImt := create(0, add(lazyImtBytecode, 0x20), mload(lazyImtBytecode))
}
}
Expand Down
23 changes: 14 additions & 9 deletions src/LinearPriceCalculator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Ownable2Step } from "openzeppelin-contracts/contracts/access/Ownable2St
import { IPriceCalculator } from "./IPriceCalculator.sol";

/// Address 0x0000...0000 was used instead of an ERC20 token address
error OnlyERC20TokensAllowed();
error OnlyTokensAllowed();

/// @title Linear Price Calculator to determine the price to acquire a membership
contract LinearPriceCalculator is IPriceCalculator, Ownable2Step {
Expand All @@ -16,18 +16,23 @@ contract LinearPriceCalculator is IPriceCalculator, Ownable2Step {
uint256 public pricePerMessagePerEpoch;

constructor(address _token, uint256 _pricePerMessagePerEpoch) Ownable2Step() {
if (_token == address(0)) revert OnlyERC20TokensAllowed();
token = _token;
pricePerMessagePerEpoch = _pricePerMessagePerEpoch;
_setTokenAndPrice(_token, _pricePerMessagePerEpoch);
}

/// Set accepted token and price per message per epoch per period
/// @param _token The token accepted by RLN membership management
/// @param _pricePerMessagePerEpoch Price per message per epoch
function setTokenAndPrice(address _token, uint256 _pricePerMessagePerEpoch) external onlyOwner {
_setTokenAndPrice(_token, _pricePerMessagePerEpoch);
}

/// Set accepted token and price per message per epoch per period
/// @param _token The token accepted by the membership management for RLN
/// @param _pricePerPeriod Price per message per epoch
function setTokenAndPrice(address _token, uint256 _pricePerPeriod) external onlyOwner {
require(_token != address(0), "only tokens can be used");
/// @param _token The token accepted by RLN membership management
/// @param _pricePerMessagePerEpoch Price per message per epoch
function _setTokenAndPrice(address _token, uint256 _pricePerMessagePerEpoch) internal {
if (_token == address(0)) revert OnlyTokensAllowed();
token = _token;
pricePerMessagePerEpoch = _pricePerPeriod;
pricePerMessagePerEpoch = _pricePerMessagePerEpoch;
}

/// Returns the token and price to pay in `token` for some `_rateLimit`
Expand Down
Loading
Loading