UNPKG

@tokamak-zk-evm/synthesizer

Version:

Tokamak zk-EVM Synthesizer - Processes Ethereum transactions into wire maps for Tokamak zk-SNARK proof generation

106 lines 6.66 kB
import { keccak256 } from 'ethereum-cryptography/keccak'; import { hexToBytes, Address, Account } from '@synthesizer-libs/util'; const IMPLEMENTATION_SLOT = '0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3'; export const setupUSDCFromCalldata = async (evm, proxyAddr, implementationV1Addr, implementationV2Addr, proxyCode, v1Code, v2Code, proxyStorageLayout, v1StorageLayout, v2StorageLayout, calldata, sender) => { console.log('=== Setting up USDC Environment ==='); console.log('Proxy address:', proxyAddr.toString()); console.log('Implementation V1 address:', implementationV1Addr.toString()); console.log('Implementation V2 address:', implementationV2Addr.toString()); // Setup all contract accounts await evm.stateManager.putAccount(proxyAddr, new Account()); await evm.stateManager.putAccount(implementationV1Addr, new Account()); await evm.stateManager.putAccount(implementationV2Addr, new Account()); await evm.stateManager.putAccount(sender, new Account()); // Deploy all contract codes await evm.stateManager.putCode(proxyAddr, proxyCode); await evm.stateManager.putCode(implementationV1Addr, v1Code); await evm.stateManager.putCode(implementationV2Addr, v2Code); // Verify code deployment const proxyDeployedCode = await evm.stateManager.getCode(proxyAddr); const v1DeployedCode = await evm.stateManager.getCode(implementationV1Addr); const v2DeployedCode = await evm.stateManager.getCode(implementationV2Addr); // Setup delegation chain with verification await evm.stateManager.putStorage(proxyAddr, hexToBytes(IMPLEMENTATION_SLOT), hexToBytes('0x' + implementationV1Addr.toString().slice(2).padStart(64, '0'))); await evm.stateManager.putStorage(implementationV1Addr, hexToBytes(IMPLEMENTATION_SLOT), hexToBytes('0x' + implementationV2Addr.toString().slice(2).padStart(64, '0'))); // Verify delegation chain const proxyImpl = await evm.stateManager.getStorage(proxyAddr, hexToBytes(IMPLEMENTATION_SLOT)); const v1Impl = await evm.stateManager.getStorage(implementationV1Addr, hexToBytes(IMPLEMENTATION_SLOT)); console.log('Proxy implementation:', Buffer.from(proxyImpl).toString('hex')); console.log('V1 implementation:', Buffer.from(v1Impl).toString('hex')); // Helper function to find balance slot in storage layout const findBalanceSlot = (layout) => { return layout.storageLayout.storage.find(item => item.label === '_balances' || item.label === 'balances')?.slot; }; // Get balance slots from each layout const proxyBalanceSlot = findBalanceSlot(proxyStorageLayout); const v1BalanceSlot = findBalanceSlot(v1StorageLayout); const v2BalanceSlot = findBalanceSlot(v2StorageLayout); // Parse calldata const params = calldata.slice(10); const functionSig = calldata.slice(0, 10); switch (functionSig) { case '0xa9059cbb': { // transfer const to = '0x' + params.slice(24, 64); const amount = BigInt('0x' + params.slice(64)); console.log('=== Setup Debug Info ==='); console.log('Sender:', sender.toString()); console.log('To:', to); console.log('Amount:', amount.toString()); // Setup recipient account await evm.stateManager.putAccount(new Address(hexToBytes(to)), new Account()); // Setup balances in all contracts if needed if (v2BalanceSlot) { // Use V2's layout as it's the final implementation console.log('v2BalanceSlot:', v2BalanceSlot); const balanceKey = keccak256(hexToBytes('0x' + sender.toString().slice(2).padStart(64, '0') + v2BalanceSlot.padStart(64, '0'))); // Set initial balance for sender const initialBalance = amount + BigInt(1000); // Some buffer await evm.stateManager.putStorage(proxyAddr, // Store in proxy's storage balanceKey, hexToBytes('0x' + initialBalance.toString(16).padStart(64, '0'))); const senderBalanceSlot = keccak256(hexToBytes('0x' + sender.toString().slice(2).padStart(64, '0') + v2BalanceSlot.padStart(64, '0'))); // 검증을 위해 저장된 값 확인 const storedBalance = await evm.stateManager.getStorage(proxyAddr, senderBalanceSlot); console.log('Stored balance:', Buffer.from(storedBalance).toString('hex')); } break; } case '0x095ea7b3': { // approve const spender = '0x' + params.slice(24, 64); const amount = BigInt('0x' + params.slice(64)); // Setup spender account await evm.stateManager.putAccount(new Address(hexToBytes(spender)), new Account()); // Find allowance slots const findAllowanceSlot = (layout) => { return layout.storageLayout.storage.find(item => item.label === 'allowed')?.slot; }; const v2AllowanceSlot = findAllowanceSlot(v2StorageLayout); if (v2AllowanceSlot) { // Calculate storage slot for allowance // allowances[owner][spender] // console.log('v2AllowanceSlot:', v2AllowanceSlot) const ownerKey = keccak256(hexToBytes('0x' + sender.toString().slice(2).padStart(64, '0') + v2AllowanceSlot.padStart(64, '0'))); const spenderKey = keccak256(hexToBytes('0x' + spender.slice(2).padStart(64, '0') + ownerKey.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '').padStart(64, '0'))); // Set initial allowance in proxy's storage await evm.stateManager.putStorage(proxyAddr, // Store in proxy's storage spenderKey, hexToBytes('0x' + amount.toString(16).padStart(64, '0')) // ); console.log('Setup allowance mapping:', { owner: sender.toString(), spender: spender, slot: v2AllowanceSlot, storageKey: Buffer.from(spenderKey).toString('hex') }); // Verify the allowance was set const currentAllowance = await evm.stateManager.getStorage(proxyAddr, spenderKey); console.log('Current allowance:', BigInt('0x' + Buffer.from(currentAllowance).toString('hex')).toString()); } break; } } console.log('USDC Environment setup completed'); console.log('=================='); }; //# sourceMappingURL=usdcEvmSetup.js.map