Merge remote-tracking branch 'origin/develop' into feat/bridge_optimization_upgrade

This commit is contained in:
zimpha
2024-02-07 13:24:53 +08:00
95 changed files with 4780 additions and 1889 deletions

View File

@@ -2,7 +2,7 @@
import * as dotenv from "dotenv";
import { ethers } from "hardhat";
import poseidonUnit from "circomlib/src/poseidon_gencontract";
import { generateABI, createCode } from "../scripts/poseidon";
dotenv.config();
@@ -15,11 +15,7 @@ async function main() {
let PoseidonUnit2Address = process.env.POSEIDON_UNIT2_ADDR;
if (!PoseidonUnit2Address) {
const Poseidon2Elements = new ethers.ContractFactory(
poseidonUnit.generateABI(2),
poseidonUnit.createCode(2),
deployer
);
const Poseidon2Elements = new ethers.ContractFactory(generateABI(2), createCode(2), deployer);
const poseidon = await Poseidon2Elements.deploy();
console.log("Deploy PoseidonUnit2 contract, hash:", poseidon.deployTransaction.hash);
@@ -28,7 +24,9 @@ async function main() {
PoseidonUnit2Address = poseidon.address;
}
const verifier = await ScrollChainCommitmentVerifier.deploy(PoseidonUnit2Address, L1ScrollChainAddress);
const verifier = await ScrollChainCommitmentVerifier.deploy(PoseidonUnit2Address, L1ScrollChainAddress, {
gasPrice: 1e9,
});
console.log("Deploy ScrollChainCommitmentVerifier contract, hash:", verifier.deployTransaction.hash);
const receipt = await verifier.deployTransaction.wait();
console.log(`✅ Deploy ScrollChainCommitmentVerifier contract at: ${verifier.address}, gas used: ${receipt.gasUsed}`);

View File

@@ -141,7 +141,7 @@ contract DeployL1BridgeContracts is Script {
}
function deployL1GatewayRouter() internal {
L1GatewayRouter impl = new L1GatewayRouter(L1_SCROLL_MESSENGER_PROXY_ADDR);
L1GatewayRouter impl = new L1GatewayRouter();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),

View File

@@ -31,6 +31,8 @@ import {ScrollStandardERC20Factory} from "../../src/libraries/token/ScrollStanda
contract DeployL2BridgeContracts is Script {
uint256 L2_DEPLOYER_PRIVATE_KEY = vm.envUint("L2_DEPLOYER_PRIVATE_KEY");
address L2_PROXY_ADMIN_ADDR = vm.envAddress("L2_PROXY_ADMIN_ADDR");
address L1_TX_FEE_RECIPIENT_ADDR = vm.envAddress("L1_TX_FEE_RECIPIENT_ADDR");
address L1_WETH_ADDR = vm.envAddress("L1_WETH_ADDR");
address L2_WETH_ADDR = vm.envAddress("L2_WETH_ADDR");
@@ -58,6 +60,8 @@ contract DeployL2BridgeContracts is Script {
address L2_WHITELIST_PREDEPLOY_ADDR = vm.envOr("L2_WHITELIST_PREDEPLOY_ADDR", address(0));
function run() external {
proxyAdmin = ProxyAdmin(L2_PROXY_ADMIN_ADDR);
vm.startBroadcast(L2_DEPLOYER_PRIVATE_KEY);
// predeploys
@@ -67,7 +71,6 @@ contract DeployL2BridgeContracts is Script {
deployL2Whitelist();
// upgradable
deployProxyAdmin();
deployL2ScrollMessenger();
deployL2GatewayRouter();
deployScrollStandardERC20Factory();
@@ -131,12 +134,6 @@ contract DeployL2BridgeContracts is Script {
logAddress("L2_WHITELIST_ADDR", address(whitelist));
}
function deployProxyAdmin() internal {
proxyAdmin = new ProxyAdmin();
logAddress("L2_PROXY_ADMIN_ADDR", address(proxyAdmin));
}
function deployL2ScrollMessenger() internal {
L2ScrollMessenger impl = new L2ScrollMessenger(L1_SCROLL_MESSENGER_PROXY_ADDR, address(queue));
@@ -144,7 +141,7 @@ contract DeployL2BridgeContracts is Script {
}
function deployL2GatewayRouter() internal {
L2GatewayRouter impl = new L2GatewayRouter(L2_SCROLL_MESSENGER_PROXY_ADDR);
L2GatewayRouter impl = new L2GatewayRouter();
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(
address(impl),
address(proxyAdmin),

View File

@@ -78,15 +78,21 @@ contract InitializeL1BridgeContracts is Script {
vm.startBroadcast(L1_DEPLOYER_PRIVATE_KEY);
// note: we use call upgrade(...) and initialize(...) instead of upgradeAndCall(...),
// otherwise the contract owner would become ProxyAdmin.
// initialize ScrollChain
proxyAdmin.upgradeAndCall(
proxyAdmin.upgrade(
ITransparentUpgradeableProxy(L1_SCROLL_CHAIN_PROXY_ADDR),
L1_SCROLL_CHAIN_IMPLEMENTATION_ADDR,
abi.encodeCall(
ScrollChain.initialize,
(L1_MESSAGE_QUEUE_PROXY_ADDR, L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR, MAX_TX_IN_CHUNK)
)
L1_SCROLL_CHAIN_IMPLEMENTATION_ADDR
);
ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).initialize(
L1_MESSAGE_QUEUE_PROXY_ADDR,
L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR,
MAX_TX_IN_CHUNK
);
ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).addSequencer(L1_COMMIT_SENDER_ADDRESS);
ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).addProver(L1_FINALIZE_SENDER_ADDRESS);
@@ -103,35 +109,32 @@ contract InitializeL1BridgeContracts is Script {
L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).updateWhitelist(L1_WHITELIST_ADDR);
// initialize L1MessageQueueWithGasPriceOracle
proxyAdmin.upgradeAndCall(
proxyAdmin.upgrade(
ITransparentUpgradeableProxy(L1_MESSAGE_QUEUE_PROXY_ADDR),
L1_MESSAGE_QUEUE_IMPLEMENTATION_ADDR,
abi.encodeCall(
L1MessageQueue.initialize,
(
L1_SCROLL_MESSENGER_PROXY_ADDR,
L1_SCROLL_CHAIN_PROXY_ADDR,
L1_ENFORCED_TX_GATEWAY_PROXY_ADDR,
L2_GAS_PRICE_ORACLE_PROXY_ADDR,
MAX_L1_MESSAGE_GAS_LIMIT
)
)
L1_MESSAGE_QUEUE_IMPLEMENTATION_ADDR
);
L1MessageQueueWithGasPriceOracle(L1_MESSAGE_QUEUE_PROXY_ADDR).initialize(
L1_SCROLL_MESSENGER_PROXY_ADDR,
L1_SCROLL_CHAIN_PROXY_ADDR,
L1_ENFORCED_TX_GATEWAY_PROXY_ADDR,
L2_GAS_PRICE_ORACLE_PROXY_ADDR,
MAX_L1_MESSAGE_GAS_LIMIT
);
L1MessageQueueWithGasPriceOracle(L1_MESSAGE_QUEUE_PROXY_ADDR).initializeV2();
// initialize L1ScrollMessenger
proxyAdmin.upgradeAndCall(
proxyAdmin.upgrade(
ITransparentUpgradeableProxy(L1_SCROLL_MESSENGER_PROXY_ADDR),
L1_SCROLL_MESSENGER_IMPLEMENTATION_ADDR,
abi.encodeCall(
L1ScrollMessenger.initialize,
(
L2_SCROLL_MESSENGER_PROXY_ADDR,
L1_FEE_VAULT_ADDR,
L1_SCROLL_CHAIN_PROXY_ADDR,
L1_MESSAGE_QUEUE_PROXY_ADDR
)
)
L1_SCROLL_MESSENGER_IMPLEMENTATION_ADDR
);
L1ScrollMessenger(payable(L1_SCROLL_MESSENGER_PROXY_ADDR)).initialize(
L2_SCROLL_MESSENGER_PROXY_ADDR,
L1_FEE_VAULT_ADDR,
L1_SCROLL_CHAIN_PROXY_ADDR,
L1_MESSAGE_QUEUE_PROXY_ADDR
);
// initialize EnforcedTxGateway
@@ -147,63 +150,72 @@ contract InitializeL1BridgeContracts is Script {
);
// initialize L1CustomERC20Gateway
proxyAdmin.upgradeAndCall(
proxyAdmin.upgrade(
ITransparentUpgradeableProxy(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR),
L1_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR,
abi.encodeCall(
L1CustomERC20Gateway.initialize,
(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR, L1_GATEWAY_ROUTER_PROXY_ADDR, L1_SCROLL_MESSENGER_PROXY_ADDR)
)
L1_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR
);
L1CustomERC20Gateway(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).initialize(
L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR,
L1_GATEWAY_ROUTER_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L1ERC1155Gateway
proxyAdmin.upgradeAndCall(
proxyAdmin.upgrade(
ITransparentUpgradeableProxy(L1_ERC1155_GATEWAY_PROXY_ADDR),
L1_ERC1155_GATEWAY_IMPLEMENTATION_ADDR,
abi.encodeCall(L1ERC1155Gateway.initialize, (L2_ERC1155_GATEWAY_PROXY_ADDR, L1_SCROLL_MESSENGER_PROXY_ADDR))
L1_ERC1155_GATEWAY_IMPLEMENTATION_ADDR
);
L1ERC1155Gateway(L1_ERC1155_GATEWAY_PROXY_ADDR).initialize(
L2_ERC1155_GATEWAY_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L1ERC721Gateway
proxyAdmin.upgradeAndCall(
proxyAdmin.upgrade(
ITransparentUpgradeableProxy(L1_ERC721_GATEWAY_PROXY_ADDR),
L1_ERC721_GATEWAY_IMPLEMENTATION_ADDR,
abi.encodeCall(L1ERC721Gateway.initialize, (L2_ERC721_GATEWAY_PROXY_ADDR, L1_SCROLL_MESSENGER_PROXY_ADDR))
L1_ERC721_GATEWAY_IMPLEMENTATION_ADDR
);
L1ERC721Gateway(L1_ERC721_GATEWAY_PROXY_ADDR).initialize(
L2_ERC721_GATEWAY_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L1ETHGateway
proxyAdmin.upgradeAndCall(
ITransparentUpgradeableProxy(L1_ETH_GATEWAY_PROXY_ADDR),
L1_ETH_GATEWAY_IMPLEMENTATION_ADDR,
abi.encodeCall(
L1ETHGateway.initialize,
(L2_ETH_GATEWAY_PROXY_ADDR, L1_GATEWAY_ROUTER_PROXY_ADDR, L1_SCROLL_MESSENGER_PROXY_ADDR)
)
proxyAdmin.upgrade(ITransparentUpgradeableProxy(L1_ETH_GATEWAY_PROXY_ADDR), L1_ETH_GATEWAY_IMPLEMENTATION_ADDR);
L1ETHGateway(L1_ETH_GATEWAY_PROXY_ADDR).initialize(
L2_ETH_GATEWAY_PROXY_ADDR,
L1_GATEWAY_ROUTER_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L1StandardERC20Gateway
proxyAdmin.upgradeAndCall(
proxyAdmin.upgrade(
ITransparentUpgradeableProxy(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR),
L1_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR,
abi.encodeCall(
L1StandardERC20Gateway.initialize,
(
L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR,
L1_GATEWAY_ROUTER_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR,
L2_SCROLL_STANDARD_ERC20_ADDR,
L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR
)
)
L1_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR
);
L1StandardERC20Gateway(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR).initialize(
L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR,
L1_GATEWAY_ROUTER_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR,
L2_SCROLL_STANDARD_ERC20_ADDR,
L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR
);
// initialize L1WETHGateway
proxyAdmin.upgradeAndCall(
proxyAdmin.upgrade(
ITransparentUpgradeableProxy(L1_WETH_GATEWAY_PROXY_ADDR),
L1_WETH_GATEWAY_IMPLEMENTATION_ADDR,
abi.encodeCall(
L1WETHGateway.initialize,
(L2_WETH_GATEWAY_PROXY_ADDR, L1_GATEWAY_ROUTER_PROXY_ADDR, L1_SCROLL_MESSENGER_PROXY_ADDR)
)
L1_WETH_GATEWAY_IMPLEMENTATION_ADDR
);
L1WETHGateway(payable(L1_WETH_GATEWAY_PROXY_ADDR)).initialize(
L2_WETH_GATEWAY_PROXY_ADDR,
L1_GATEWAY_ROUTER_PROXY_ADDR,
L1_SCROLL_MESSENGER_PROXY_ADDR
);
// set WETH gateway in router

View File

@@ -67,6 +67,9 @@ contract InitializeL2BridgeContracts is Script {
vm.startBroadcast(deployerPrivateKey);
// note: we use call upgrade(...) and initialize(...) instead of upgradeAndCall(...),
// otherwise the contract owner would become ProxyAdmin.
// initialize L2MessageQueue
L2MessageQueue(L2_MESSAGE_QUEUE_ADDR).initialize(L2_SCROLL_MESSENGER_PROXY_ADDR);
@@ -77,12 +80,13 @@ contract InitializeL2BridgeContracts is Script {
L1GasPriceOracle(L1_GAS_PRICE_ORACLE_ADDR).updateWhitelist(L2_WHITELIST_ADDR);
// initialize L2ScrollMessenger
proxyAdmin.upgradeAndCall(
proxyAdmin.upgrade(
ITransparentUpgradeableProxy(L2_SCROLL_MESSENGER_PROXY_ADDR),
L2_SCROLL_MESSENGER_IMPLEMENTATION_ADDR,
abi.encodeCall(L2ScrollMessenger.initialize, (L1_SCROLL_MESSENGER_PROXY_ADDR))
L2_SCROLL_MESSENGER_IMPLEMENTATION_ADDR
);
L2ScrollMessenger(payable(L2_SCROLL_MESSENGER_PROXY_ADDR)).initialize(L1_SCROLL_MESSENGER_PROXY_ADDR);
// initialize L2GatewayRouter
L2GatewayRouter(L2_GATEWAY_ROUTER_PROXY_ADDR).initialize(
L2_ETH_GATEWAY_PROXY_ADDR,
@@ -90,62 +94,71 @@ contract InitializeL2BridgeContracts is Script {
);
// initialize L2CustomERC20Gateway
proxyAdmin.upgradeAndCall(
proxyAdmin.upgrade(
ITransparentUpgradeableProxy(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR),
L2_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR,
abi.encodeCall(
L2CustomERC20Gateway.initialize,
(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR, L2_GATEWAY_ROUTER_PROXY_ADDR, L2_SCROLL_MESSENGER_PROXY_ADDR)
)
L2_CUSTOM_ERC20_GATEWAY_IMPLEMENTATION_ADDR
);
L2CustomERC20Gateway(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).initialize(
L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR,
L2_GATEWAY_ROUTER_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L2ERC1155Gateway
proxyAdmin.upgradeAndCall(
proxyAdmin.upgrade(
ITransparentUpgradeableProxy(L2_ERC1155_GATEWAY_PROXY_ADDR),
L2_ERC1155_GATEWAY_IMPLEMENTATION_ADDR,
abi.encodeCall(L2ERC1155Gateway.initialize, (L1_ERC1155_GATEWAY_PROXY_ADDR, L2_SCROLL_MESSENGER_PROXY_ADDR))
L2_ERC1155_GATEWAY_IMPLEMENTATION_ADDR
);
L2ERC1155Gateway(L2_ERC1155_GATEWAY_PROXY_ADDR).initialize(
L1_ERC1155_GATEWAY_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L2ERC721Gateway
proxyAdmin.upgradeAndCall(
proxyAdmin.upgrade(
ITransparentUpgradeableProxy(L2_ERC721_GATEWAY_PROXY_ADDR),
L2_ERC721_GATEWAY_IMPLEMENTATION_ADDR,
abi.encodeCall(L2ERC721Gateway.initialize, (L1_ERC721_GATEWAY_PROXY_ADDR, L2_SCROLL_MESSENGER_PROXY_ADDR))
L2_ERC721_GATEWAY_IMPLEMENTATION_ADDR
);
L2ERC721Gateway(L2_ERC721_GATEWAY_PROXY_ADDR).initialize(
L1_ERC721_GATEWAY_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L2ETHGateway
proxyAdmin.upgradeAndCall(
ITransparentUpgradeableProxy(L2_ETH_GATEWAY_PROXY_ADDR),
L2_ETH_GATEWAY_IMPLEMENTATION_ADDR,
abi.encodeCall(
L2ETHGateway.initialize,
(L1_ETH_GATEWAY_PROXY_ADDR, L2_GATEWAY_ROUTER_PROXY_ADDR, L2_SCROLL_MESSENGER_PROXY_ADDR)
)
proxyAdmin.upgrade(ITransparentUpgradeableProxy(L2_ETH_GATEWAY_PROXY_ADDR), L2_ETH_GATEWAY_IMPLEMENTATION_ADDR);
L2ETHGateway(L2_ETH_GATEWAY_PROXY_ADDR).initialize(
L1_ETH_GATEWAY_PROXY_ADDR,
L2_GATEWAY_ROUTER_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR
);
// initialize L2StandardERC20Gateway
proxyAdmin.upgradeAndCall(
proxyAdmin.upgrade(
ITransparentUpgradeableProxy(L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR),
L2_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR,
abi.encodeCall(
L2StandardERC20Gateway.initialize,
(
L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR,
L2_GATEWAY_ROUTER_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR,
L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR
)
)
L2_STANDARD_ERC20_GATEWAY_IMPLEMENTATION_ADDR
);
L2StandardERC20Gateway(L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR).initialize(
L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR,
L2_GATEWAY_ROUTER_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR,
L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR
);
// initialize L2WETHGateway
proxyAdmin.upgradeAndCall(
proxyAdmin.upgrade(
ITransparentUpgradeableProxy(L2_WETH_GATEWAY_PROXY_ADDR),
L2_WETH_GATEWAY_IMPLEMENTATION_ADDR,
abi.encodeCall(
L2WETHGateway.initialize,
(L1_WETH_GATEWAY_PROXY_ADDR, L2_GATEWAY_ROUTER_PROXY_ADDR, L2_SCROLL_MESSENGER_PROXY_ADDR)
)
L2_WETH_GATEWAY_IMPLEMENTATION_ADDR
);
L2WETHGateway(payable(L2_WETH_GATEWAY_PROXY_ADDR)).initialize(
L1_WETH_GATEWAY_PROXY_ADDR,
L2_GATEWAY_ROUTER_PROXY_ADDR,
L2_SCROLL_MESSENGER_PROXY_ADDR
);
// set WETH gateway in router

View File

@@ -0,0 +1,202 @@
/* eslint-disable node/no-missing-import */
import { ethers } from "ethers";
import Contract from "circomlib/src/evmasm";
import * as constants from "circomlib/src/poseidon_constants";
const N_ROUNDS_F = 8;
const N_ROUNDS_P = [56, 57, 56, 60, 60, 63, 64, 63];
export function createCode(nInputs: number) {
if (nInputs < 1 || nInputs > 8) throw new Error("Invalid number of inputs. Must be 1<=nInputs<=8");
const t = nInputs + 1;
const nRoundsF = N_ROUNDS_F;
const nRoundsP = N_ROUNDS_P[t - 2];
const C = new Contract();
function saveM() {
for (let i = 0; i < t; i++) {
for (let j = 0; j < t; j++) {
C.push(constants.M[t - 2][i][j]);
C.push((1 + i * t + j) * 32);
C.mstore();
}
}
}
function ark(r: number) {
// st, q
for (let i = 0; i < t; i++) {
C.dup(t); // q, st, q
C.push(constants.C[t - 2][r * t + i]); // K, q, st, q
C.dup(2 + i); // st[i], K, q, st, q
C.addmod(); // newSt[i], st, q
C.swap(1 + i); // xx, st, q
C.pop();
}
}
function sigma(p: number) {
// sq, q
C.dup(t); // q, st, q
C.dup(1 + p); // st[p] , q , st, q
C.dup(1); // q, st[p] , q , st, q
C.dup(0); // q, q, st[p] , q , st, q
C.dup(2); // st[p] , q, q, st[p] , q , st, q
C.dup(0); // st[p] , st[p] , q, q, st[p] , q , st, q
C.mulmod(); // st2[p], q, st[p] , q , st, q
C.dup(0); // st2[p], st2[p], q, st[p] , q , st, q
C.mulmod(); // st4[p], st[p] , q , st, q
C.mulmod(); // st5[p], st, q
C.swap(1 + p);
C.pop(); // newst, q
}
function mix() {
C.label("mix");
for (let i = 0; i < t; i++) {
for (let j = 0; j < t; j++) {
if (j === 0) {
C.dup(i + t); // q, newSt, oldSt, q
C.push((1 + i * t + j) * 32);
C.mload(); // M, q, newSt, oldSt, q
C.dup(2 + i + j); // oldSt[j], M, q, newSt, oldSt, q
C.mulmod(); // acc, newSt, oldSt, q
} else {
C.dup(1 + i + t); // q, acc, newSt, oldSt, q
C.push((1 + i * t + j) * 32);
C.mload(); // M, q, acc, newSt, oldSt, q
C.dup(3 + i + j); // oldSt[j], M, q, acc, newSt, oldSt, q
C.mulmod(); // aux, acc, newSt, oldSt, q
C.dup(2 + i + t); // q, aux, acc, newSt, oldSt, q
C.swap(2); // acc, aux, q, newSt, oldSt, q
C.addmod(); // acc, newSt, oldSt, q
}
}
}
for (let i = 0; i < t; i++) {
C.swap(t - i + (t - i - 1));
C.pop();
}
C.push(0);
C.mload();
C.jmp();
}
// Check selector
C.push("0x0100000000000000000000000000000000000000000000000000000000");
C.push(0);
C.calldataload();
C.div();
C.dup(0);
C.push(ethers.utils.keccak256(ethers.utils.toUtf8Bytes(`poseidon(uint256[${nInputs}],uint256)`)).slice(0, 10)); // poseidon(uint256[n],uint256)
C.eq();
C.swap(1);
C.push(ethers.utils.keccak256(ethers.utils.toUtf8Bytes(`poseidon(bytes32[${nInputs}],bytes32)`)).slice(0, 10)); // poseidon(bytes32[n],bytes32)
C.eq();
C.or();
C.jmpi("start");
C.invalid();
C.label("start");
saveM();
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
// Load t values from the call data.
// The function has a single array param param
// [Selector (4)] [item1 (32)] [item2 (32)] .... [doman (32)]
// Stack positions 0-nInputs.
for (let i = 0; i < nInputs; i++) {
C.push(0x04 + 0x20 * (nInputs - i - 1));
C.calldataload();
}
C.push(0x04 + 0x20 * nInputs);
C.calldataload();
for (let i = 0; i < nRoundsF + nRoundsP; i++) {
ark(i);
if (i < nRoundsF / 2 || i >= nRoundsP + nRoundsF / 2) {
for (let j = 0; j < t; j++) {
sigma(j);
}
} else {
sigma(0);
}
const strLabel = "aferMix" + i;
C._pushLabel(strLabel);
C.push(0);
C.mstore();
C.jmp("mix");
C.label(strLabel);
}
C.push("0x00");
C.mstore(); // Save it to pos 0;
C.push("0x20");
C.push("0x00");
C.return();
mix();
return C.createTxData();
}
export function generateABI(nInputs: number) {
return [
{
constant: true,
inputs: [
{
internalType: `bytes32[${nInputs}]`,
name: "input",
type: `bytes32[${nInputs}]`,
},
{
internalType: "bytes32",
name: "domain",
type: "bytes32",
},
],
name: "poseidon",
outputs: [
{
internalType: "bytes32",
name: "",
type: "bytes32",
},
],
payable: false,
stateMutability: "pure",
type: "function",
},
{
constant: true,
inputs: [
{
internalType: `uint256[${nInputs}]`,
name: "input",
type: `uint256[${nInputs}]`,
},
{
internalType: "uint256",
name: "domain",
type: "uint256",
},
],
name: "poseidon",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
payable: false,
stateMutability: "pure",
type: "function",
},
];
}