diff --git a/crates/primitives/src/abi.rs b/crates/primitives/src/abi.rs index 1da5ffbd8..eb5b5126c 100644 --- a/crates/primitives/src/abi.rs +++ b/crates/primitives/src/abi.rs @@ -386,12 +386,11 @@ macro_rules! define_abi { } /// Decryption data provided by the sequencer for encrypted deposits. + /// The decrypted (to, memo) are derived on-chain from the AES-GCM decryption. #[derive(Debug)] struct DecryptionData { bytes32 sharedSecret; uint8 sharedSecretYParity; - address to; - bytes32 memo; ChaumPedersenProof cpProof; } diff --git a/crates/tempo-zone/src/builder.rs b/crates/tempo-zone/src/builder.rs index 0a21c3757..817942c5c 100644 --- a/crates/tempo-zone/src/builder.rs +++ b/crates/tempo-zone/src/builder.rs @@ -689,8 +689,6 @@ mod tests { decryptions: vec![abi::DecryptionData { sharedSecret: B256::ZERO, sharedSecretYParity: 0x02, - to: sender, - memo: B256::ZERO, cpProof: abi::ChaumPedersenProof { s: B256::ZERO, c: B256::ZERO, diff --git a/crates/tempo-zone/src/l1.rs b/crates/tempo-zone/src/l1.rs index ca56816bf..ea77776c9 100644 --- a/crates/tempo-zone/src/l1.rs +++ b/crates/tempo-zone/src/l1.rs @@ -1126,7 +1126,7 @@ impl L1BlockDeposits { self, sequencer_key: &k256::SecretKey, portal_address: Address, - policy_provider: &crate::l1_state::PolicyProvider, + _policy_provider: &crate::l1_state::PolicyProvider, ) -> eyre::Result { use crate::precompiles::ecies; @@ -1192,46 +1192,15 @@ impl L1BlockDeposits { recipient = %dec.to, token = %d.token, amount = %d.amount, - "Decrypted encrypted deposit, checking policy" + "Decrypted encrypted deposit" ); - // Check TIP-403 policy via the provider (cache-first, RPC fallback). - // Errors are propagated so the engine retries rather than allowing - // unauthorized deposits through. - let authorized = policy_provider - .is_authorized_async( - d.token, - dec.to, - l1_block_number, - crate::l1_state::AuthRole::MintRecipient, - ) - .await?; - - let recipient = if authorized { - debug!( - target: "zone::engine", - recipient = %dec.to, - token = %d.token, - "Policy authorized encrypted deposit recipient" - ); - dec.to - } else { - warn!( - target: "zone::engine", - sender = %d.sender, - recipient = %dec.to, - token = %d.token, - amount = %d.amount, - "Encrypted deposit recipient unauthorized, redirecting to sender" - ); - d.sender - }; - + // TIP-403 policy enforcement happens on-chain: ZoneInbox + // wraps the mint in try/catch and falls back to crediting + // the depositor if the recipient is unauthorized. let decryption = abi::DecryptionData { sharedSecret: dec.proof.shared_secret, sharedSecretYParity: dec.proof.shared_secret_y_parity, - to: recipient, - memo: dec.memo, cpProof: abi::ChaumPedersenProof { s: dec.proof.cp_proof_s, c: dec.proof.cp_proof_c, @@ -1259,8 +1228,6 @@ impl L1BlockDeposits { let decryption = abi::DecryptionData { sharedSecret: proof.shared_secret, sharedSecretYParity: proof.shared_secret_y_parity, - to: d.sender, - memo: B256::ZERO, cpProof: abi::ChaumPedersenProof { s: proof.cp_proof_s, c: proof.cp_proof_c, @@ -1280,8 +1247,6 @@ impl L1BlockDeposits { let decryption = abi::DecryptionData { sharedSecret: B256::ZERO, sharedSecretYParity: 0x02, - to: d.sender, - memo: B256::ZERO, cpProof: abi::ChaumPedersenProof { s: B256::ZERO, c: B256::ZERO, diff --git a/crates/tempo-zone/tests/advance_tempo.rs b/crates/tempo-zone/tests/advance_tempo.rs index 5476702e5..ce800ff31 100644 --- a/crates/tempo-zone/tests/advance_tempo.rs +++ b/crates/tempo-zone/tests/advance_tempo.rs @@ -38,8 +38,6 @@ sol! { struct DecryptionData { bytes32 sharedSecret; uint8 sharedSecretYParity; - address to; - bytes32 memo; ChaumPedersenProof cpProof; } struct EnabledToken { diff --git a/crates/tempo-zone/tests/assets/zone-test-genesis.json b/crates/tempo-zone/tests/assets/zone-test-genesis.json index 3990561cf..8f42a913f 100644 --- a/crates/tempo-zone/tests/assets/zone-test-genesis.json +++ b/crates/tempo-zone/tests/assets/zone-test-genesis.json @@ -41,7 +41,7 @@ "0x1c00000000000000000000000000000000000000": { "nonce": "0x1", "balance": "0x0", - "code": "0x60806040526004361015610011575f80fd5b5f3560e01c80631d04645f146101245780632245d0831461011f5780632e224dee1461011a5780633d7a27611461011557806346903867146101105780634732f8bb1461010b57806352d922a51461010657806358c3659914610101578063615cf854146100fc5780636aba6931146100f757806380a4cbc8146100f257806381e3da6b146100ed5780639a7361eb146100e8578063c334cd20146100e3578063f3b52855146100de578063f495be0b146100d95763fe770099146100d4575f80fd5b61052e565b610505565b6104dc565b6104bf565b6104a2565b610345565b610329565b6102b1565b61023a565b610214565b6101f7565b6101d1565b6101b1565b610194565b610177565b61014e565b3461014a575f36600319011261014a5760206001600160401b0360075416604051908152f35b5f80fd5b3461014a575f36600319011261014a5760206001600160401b0360015460401c16604051908152f35b3461014a575f36600319011261014a576020600454604051908152f35b3461014a575f36600319011261014a576020600954604051908152f35b3461014a575f36600319011261014a57602060075460c01c604051908152f35b3461014a575f36600319011261014a5760206001600160401b0360085416604051908152f35b3461014a575f36600319011261014a576020600254604051908152f35b3461014a575f36600319011261014a5760206001600160401b0360015416604051908152f35b3461014a575f36600319011261014a576003546040516001600160a01b039091168152602090f35b600435906001600160a01b038216820361014a57565b60206040818301928281528451809452019201905f5b81811061029b5750505090565b825184526020938401939092019160010161028e565b3461014a57604036600319011261014a576102ca610262565b6024356001600160401b03811161014a573660238201121561014a5780600401356001600160401b03811161014a573660248260051b8401011161014a57610325926024610319930190610655565b60405191829182610278565b0390f35b3461014a575f36600319011261014a5760205f54604051908152f35b3461014a57604036600319011261014a5761035e610262565b3360016007609a1b01141580610491575b80610480575b61041557600754604051631e7d027560e31b81526001600160a01b03909216600483015260248035908301526001600160401b0316604482015260208160648160046007609a1b015afa801561041057610325915f916103e1575b506040519081529081906020820190565b610403915060203d602011610409575b6103fb8183610742565b8101906107f6565b5f6103d0565b503d6103f1565b6107eb565b60405162461bcd60e51b815260206004820152603b60248201527f54656d706f53746174653a206f6e6c79207a6f6e652073797374656d20636f6e60448201527f7472616374732063616e20726561642054656d706f20737461746500000000006064820152608490fd5b503360036007609a1b011415610375565b503360026007609a1b01141561036f565b3461014a575f36600319011261014a576020600554604051908152f35b3461014a575f36600319011261014a576020600654604051908152f35b3461014a575f36600319011261014a5760206001600160401b0360075460401c16604051908152f35b3461014a575f36600319011261014a5760206001600160401b0360075460801c16604051908152f35b3461014a57602036600319011261014a576004356001600160401b03811161014a573660238201121561014a578060040135906001600160401b03821161014a57366024838301011161014a576007609a1b193301610646576105b26105ad5f54926105a26007546001600160401b031690565b946024369201610805565b6108c6565b60025403610637576001600160401b036105ec6105e06105da6007546001600160401b031690565b9361085e565b6001600160401b031690565b9116908103610628575f546004546040519081527fdd85219569c3c880f014955916f426d1ca039714b59ce33e24f151f155ac26b990602090a3005b631391e11b60e21b5f5260045ffd5b63591c836760e01b5f5260045ffd5b6303300c7360e31b5f5260045ffd5b91903360016007609a1b0114158061071d575b8061070c575b61041557600754604051632593f8c960e01b81526001600160a01b03909416600485015260606024850152606484018390526001600160401b03166001600160fb1b03831161014a578380926084925f9560051b8092858501376044830152810103018160046007609a1b015afa908115610410575f916106ed575090565b61070991503d805f833e6107018183610742565b810190610768565b90565b503360036007609a1b01141561066e565b503360026007609a1b011415610668565b634e487b7160e01b5f52604160045260245ffd5b90601f801991011681019081106001600160401b0382111761076357604052565b61072e565b60208183031261014a578051906001600160401b03821161014a57019080601f8301121561014a578151916001600160401b038311610763578260051b90604051936107b76020840186610742565b845260208085019282010192831161014a57602001905b8282106107db5750505090565b81518152602091820191016107ce565b6040513d5f823e3d90fd5b9081602091031261014a575190565b9291926001600160401b038211610763576040519161082e601f8201601f191660200184610742565b82948184528183011161014a578281602093845f960137010152565b634e487b7160e01b5f52601160045260245ffd5b6001600160401b036001911601906001600160401b03821161087c57565b61084a565b906001820180921161087c57565b600101908160011161087c57565b906021820180921161087c57565b906015820180921161087c57565b9190820180921161087c57565b805160208201205f556108d881610c28565b80915015610ba85761098b61095a61091c836109166108fa6109939688610dd1565b6001600160401b03166001600160401b03196001541617600155565b85610ea6565b905061095461092b8287610dd1565b67ffffffffffffffff60401b6001549160401b169067ffffffffffffffff60401b191617600155565b84610ea6565b90506109856109698286610dd1565b6001600160401b03166001600160401b03196008541617600855565b83610ea6565b905082610d0e565b91908215610ba857610b77610b6f610b5b610b53610b1f610add610aa5610a74610a6c610a648b610a5e610a598f610a3c610a286109f16109e9846109e36109de610a50978b611020565b600255565b88610ea6565b905087610ea6565b9050610a22610a0082896110f0565b60018060a01b03166bffffffffffffffffffffffff60a01b6003541617600355565b86610ea6565b9050610916610a378288611020565b600455565b9050610954610a4b8287611020565b600555565b93849150611020565b600655565b8c610ea6565b90508b610ea6565b90508a610ea6565b9050610a9f610a83828c610dd1565b6001600160401b03166001600160401b03196007541617600755565b89610ea6565b90506109e3610ab4828b610dd1565b67ffffffffffffffff60401b6007549160401b169067ffffffffffffffff60401b191617600755565b9050610b19610aec828a610dd1565b6007805467ffffffffffffffff60801b191660809290921b67ffffffffffffffff60801b16919091179055565b87610ea6565b9050610a22610b2e8289610dd1565b600780546001600160c01b031660c09290921b6001600160c01b031916919091179055565b905085610ea6565b9050610954610b6a8287611020565b600955565b905083610ea6565b9050905b610b8581856108b9565b821015610ba257610b99610b859284610ea6565b90509150610b7b565b50505050565b6305787a5560e41b5f5260045ffd5b908151811015610bc8570160200190565b634e487b7160e01b5f52603260045260245ffd5b60ff60f6199116019060ff821161087c57565b60ff60bf199116019060ff821161087c57565b60ff607f199116019060ff821161087c57565b60ff60b6199116019060ff821161087c57565b805115610d0757610c53610c4d610c3f5f84610bb7565b516001600160f81b03191690565b60f81c90565b9060ff821660bf8111610c69575050505f905f90565b60f710610c8d5750610c7d610c8391610bef565b60ff1690565b906107095f610881565b9190610c7d610c9b91610bdc565b610cad81610ca85f610881565b6108b9565b835110610cff575f925f905b828210610ccf57505061070990610ca85f610881565b909360019060081b610cf6610c7d610c4d610c3f610cf08a610ca85f610881565b87610bb7565b17940190610cb9565b505f91508190565b505f905f90565b9190918051831015610cff57610d2a610c4d610c3f8584610bb7565b9060ff821660bf8111610d425750505090505f905f90565b60f710610d5f5750610d59610c7d61070992610bef565b92610881565b9290610c7d610d6d91610bdc565b90610d7b82610ca883610881565b845110610dc7575f935f905b838210610d9d57505090610ca861070992610881565b909460019060081b610dbe610c7d610c4d610c3f610cf08b610ca88a610881565b17950190610d87565b505090505f905f90565b8051821015610ba857610dea610c4d610c3f8484610bb7565b60ff81169290607f8411610dfe5750505090565b90919392608081145f14610e1457505f93505050565b60818110159081610e9a575b5015610ba857610c7d610e3291610c02565b90610e4082610ca883610881565b845110610ba85792905f935f925b828410610e5b5750505050565b90919294610e7660019167ffffffffffffff009060081b1690565b610e8f610c7d610c4d610c3f610cf08b610ca88a610881565b179501929190610e4e565b6088915011155f610e20565b9190918051831015610ba857610ec2610c4d610c3f8584610bb7565b9060ff8216607f8111610ee15750505090610edc90610881565b600191565b60b78111610f0c575050610efa610c7d61070992610c02565b610ca8610f068261088f565b94610881565b60bf8111610f78575090610c7d610f2291610c15565b5f915f905b828210610f4e57505090610ca882610ca8610f4884610ca86107099761088f565b96610881565b909260019060081b610f6f610c7d610c4d610c3f610cf089610ca88d610881565b17930190610f27565b60f710610f8f5750610efa610c7d61070992610bef565b90610c7d610f9c91610bdc565b5f915f905b828210610fc257505090610ca882610ca8610f4884610ca86107099761088f565b909260019060081b610fe3610c7d610c4d610c3f610cf089610ca88d610881565b17930190610fa1565b602003906020821161087c57565b5f1981019190821161087c57565b600381901b91906001600160fd1b0381160361087c57565b908151811015610ba85761103a610c4d610c3f8385610bb7565b60ff81169060a082036110615750506110528161089d565b825110610ba857016021015190565b909290607f84116110725750505090565b909192608081101590816110e4575b5015610ba857610c7d61109391610c02565b91826110a0575050505f90565b60208311610ba8576110b583610ca883610881565b825110610ba8576110d96110d460216001936110df9501015194610fec565b611008565b1b610ffa565b191690565b60b7915011155f611081565b908151811015610ba85760ff61110c610c4d610c3f8486610bb7565b1660948103611131575061111f816108ab565b825110610ba857016021015160601c90565b608014159150610ba89050575f9056fea2646970667358221220edf4c2545437da93d3b806c70cbb2dec6940eaf8cf99e5dbda66a3e0192368b064736f6c63430008210033", + "code": "0x60806040526004361015610011575f80fd5b5f3560e01c80631d04645f146101245780632245d0831461011f5780632e224dee1461011a5780633d7a27611461011557806346903867146101105780634732f8bb1461010b57806352d922a51461010657806358c3659914610101578063615cf854146100fc5780636aba6931146100f757806380a4cbc8146100f257806381e3da6b146100ed5780639a7361eb146100e8578063c334cd20146100e3578063f3b52855146100de578063f495be0b146100d95763fe770099146100d4575f80fd5b61052e565b610505565b6104dc565b6104bf565b6104a2565b610345565b610329565b6102b1565b61023a565b610214565b6101f7565b6101d1565b6101b1565b610194565b610177565b61014e565b3461014a575f36600319011261014a5760206001600160401b0360075416604051908152f35b5f80fd5b3461014a575f36600319011261014a5760206001600160401b0360015460401c16604051908152f35b3461014a575f36600319011261014a576020600454604051908152f35b3461014a575f36600319011261014a576020600954604051908152f35b3461014a575f36600319011261014a57602060075460c01c604051908152f35b3461014a575f36600319011261014a5760206001600160401b0360085416604051908152f35b3461014a575f36600319011261014a576020600254604051908152f35b3461014a575f36600319011261014a5760206001600160401b0360015416604051908152f35b3461014a575f36600319011261014a576003546040516001600160a01b039091168152602090f35b600435906001600160a01b038216820361014a57565b60206040818301928281528451809452019201905f5b81811061029b5750505090565b825184526020938401939092019160010161028e565b3461014a57604036600319011261014a576102ca610262565b6024356001600160401b03811161014a573660238201121561014a5780600401356001600160401b03811161014a573660248260051b8401011161014a57610325926024610319930190610655565b60405191829182610278565b0390f35b3461014a575f36600319011261014a5760205f54604051908152f35b3461014a57604036600319011261014a5761035e610262565b3360016007609a1b01141580610491575b80610480575b61041557600754604051631e7d027560e31b81526001600160a01b03909216600483015260248035908301526001600160401b0316604482015260208160648160046007609a1b015afa801561041057610325915f916103e1575b506040519081529081906020820190565b610403915060203d602011610409575b6103fb8183610742565b8101906107f6565b5f6103d0565b503d6103f1565b6107eb565b60405162461bcd60e51b815260206004820152603b60248201527f54656d706f53746174653a206f6e6c79207a6f6e652073797374656d20636f6e60448201527f7472616374732063616e20726561642054656d706f20737461746500000000006064820152608490fd5b503360036007609a1b011415610375565b503360026007609a1b01141561036f565b3461014a575f36600319011261014a576020600554604051908152f35b3461014a575f36600319011261014a576020600654604051908152f35b3461014a575f36600319011261014a5760206001600160401b0360075460401c16604051908152f35b3461014a575f36600319011261014a5760206001600160401b0360075460801c16604051908152f35b3461014a57602036600319011261014a576004356001600160401b03811161014a573660238201121561014a578060040135906001600160401b03821161014a57366024838301011161014a576007609a1b193301610646576105b26105ad5f54926105a26007546001600160401b031690565b946024369201610805565b6108c6565b60025403610637576001600160401b036105ec6105e06105da6007546001600160401b031690565b9361085e565b6001600160401b031690565b9116908103610628575f546004546040519081527fdd85219569c3c880f014955916f426d1ca039714b59ce33e24f151f155ac26b990602090a3005b631391e11b60e21b5f5260045ffd5b63591c836760e01b5f5260045ffd5b6303300c7360e31b5f5260045ffd5b91903360016007609a1b0114158061071d575b8061070c575b61041557600754604051632593f8c960e01b81526001600160a01b03909416600485015260606024850152606484018390526001600160401b03166001600160fb1b03831161014a578380926084925f9560051b8092858501376044830152810103018160046007609a1b015afa908115610410575f916106ed575090565b61070991503d805f833e6107018183610742565b810190610768565b90565b503360036007609a1b01141561066e565b503360026007609a1b011415610668565b634e487b7160e01b5f52604160045260245ffd5b90601f801991011681019081106001600160401b0382111761076357604052565b61072e565b60208183031261014a578051906001600160401b03821161014a57019080601f8301121561014a578151916001600160401b038311610763578260051b90604051936107b76020840186610742565b845260208085019282010192831161014a57602001905b8282106107db5750505090565b81518152602091820191016107ce565b6040513d5f823e3d90fd5b9081602091031261014a575190565b9291926001600160401b038211610763576040519161082e601f8201601f191660200184610742565b82948184528183011161014a578281602093845f960137010152565b634e487b7160e01b5f52601160045260245ffd5b6001600160401b036001911601906001600160401b03821161087c57565b61084a565b906001820180921161087c57565b600101908160011161087c57565b906021820180921161087c57565b906015820180921161087c57565b9190820180921161087c57565b805160208201205f556108d881610c28565b80915015610ba85761098b61095a61091c836109166108fa6109939688610dd1565b6001600160401b03166001600160401b03196001541617600155565b85610ea6565b905061095461092b8287610dd1565b67ffffffffffffffff60401b6001549160401b169067ffffffffffffffff60401b191617600155565b84610ea6565b90506109856109698286610dd1565b6001600160401b03166001600160401b03196008541617600855565b83610ea6565b905082610d0e565b91908215610ba857610b77610b6f610b5b610b53610b1f610add610aa5610a74610a6c610a648b610a5e610a598f610a3c610a286109f16109e9846109e36109de610a50978b611020565b600255565b88610ea6565b905087610ea6565b9050610a22610a0082896110f0565b60018060a01b03166bffffffffffffffffffffffff60a01b6003541617600355565b86610ea6565b9050610916610a378288611020565b600455565b9050610954610a4b8287611020565b600555565b93849150611020565b600655565b8c610ea6565b90508b610ea6565b90508a610ea6565b9050610a9f610a83828c610dd1565b6001600160401b03166001600160401b03196007541617600755565b89610ea6565b90506109e3610ab4828b610dd1565b67ffffffffffffffff60401b6007549160401b169067ffffffffffffffff60401b191617600755565b9050610b19610aec828a610dd1565b6007805467ffffffffffffffff60801b191660809290921b67ffffffffffffffff60801b16919091179055565b87610ea6565b9050610a22610b2e8289610dd1565b600780546001600160c01b031660c09290921b6001600160c01b031916919091179055565b905085610ea6565b9050610954610b6a8287611020565b600955565b905083610ea6565b9050905b610b8581856108b9565b821015610ba257610b99610b859284610ea6565b90509150610b7b565b50505050565b6305787a5560e41b5f5260045ffd5b908151811015610bc8570160200190565b634e487b7160e01b5f52603260045260245ffd5b60ff60f6199116019060ff821161087c57565b60ff60bf199116019060ff821161087c57565b60ff607f199116019060ff821161087c57565b60ff60b6199116019060ff821161087c57565b805115610d0757610c53610c4d610c3f5f84610bb7565b516001600160f81b03191690565b60f81c90565b9060ff821660bf8111610c69575050505f905f90565b60f710610c8d5750610c7d610c8391610bef565b60ff1690565b906107095f610881565b9190610c7d610c9b91610bdc565b610cad81610ca85f610881565b6108b9565b835110610cff575f925f905b828210610ccf57505061070990610ca85f610881565b909360019060081b610cf6610c7d610c4d610c3f610cf08a610ca85f610881565b87610bb7565b17940190610cb9565b505f91508190565b505f905f90565b9190918051831015610cff57610d2a610c4d610c3f8584610bb7565b9060ff821660bf8111610d425750505090505f905f90565b60f710610d5f5750610d59610c7d61070992610bef565b92610881565b9290610c7d610d6d91610bdc565b90610d7b82610ca883610881565b845110610dc7575f935f905b838210610d9d57505090610ca861070992610881565b909460019060081b610dbe610c7d610c4d610c3f610cf08b610ca88a610881565b17950190610d87565b505090505f905f90565b8051821015610ba857610dea610c4d610c3f8484610bb7565b60ff81169290607f8411610dfe5750505090565b90919392608081145f14610e1457505f93505050565b60818110159081610e9a575b5015610ba857610c7d610e3291610c02565b90610e4082610ca883610881565b845110610ba85792905f935f925b828410610e5b5750505050565b90919294610e7660019167ffffffffffffff009060081b1690565b610e8f610c7d610c4d610c3f610cf08b610ca88a610881565b179501929190610e4e565b6088915011155f610e20565b9190918051831015610ba857610ec2610c4d610c3f8584610bb7565b9060ff8216607f8111610ee15750505090610edc90610881565b600191565b60b78111610f0c575050610efa610c7d61070992610c02565b610ca8610f068261088f565b94610881565b60bf8111610f78575090610c7d610f2291610c15565b5f915f905b828210610f4e57505090610ca882610ca8610f4884610ca86107099761088f565b96610881565b909260019060081b610f6f610c7d610c4d610c3f610cf089610ca88d610881565b17930190610f27565b60f710610f8f5750610efa610c7d61070992610bef565b90610c7d610f9c91610bdc565b5f915f905b828210610fc257505090610ca882610ca8610f4884610ca86107099761088f565b909260019060081b610fe3610c7d610c4d610c3f610cf089610ca88d610881565b17930190610fa1565b602003906020821161087c57565b5f1981019190821161087c57565b600381901b91906001600160fd1b0381160361087c57565b908151811015610ba85761103a610c4d610c3f8385610bb7565b60ff81169060a082036110615750506110528161089d565b825110610ba857016021015190565b909290607f84116110725750505090565b909192608081101590816110e4575b5015610ba857610c7d61109391610c02565b91826110a0575050505f90565b60208311610ba8576110b583610ca883610881565b825110610ba8576110d96110d460216001936110df9501015194610fec565b611008565b1b610ffa565b191690565b60b7915011155f611081565b908151811015610ba85760ff61110c610c4d610c3f8486610bb7565b1660948103611131575061111f816108ab565b825110610ba857016021015160601c90565b608014159150610ba89050575f9056fea264697066735822122057b3592454e545ec01075f02fbae633b4e6428716576ab0cafcfaa18082bb5d064736f6c634300081e0033", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0xb049644b1d5a0ec9d785dd48f95099e0f566112084acb1ba0814112209b432a1", "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -58,17 +58,17 @@ "0x1c00000000000000000000000000000000000001": { "nonce": "0x1", "balance": "0x0", - "code": "0x60806040526004361015610011575f80fd5b5f3560e01c80631fbb25ad146100745780632d4884821461006f57806379502c551461006a57806382648c3b14610065578063a21de6d9146100605763d01e8d311461005b575f80fd5b6101f0565b61014c565b610130565b6100ec565b6100c6565b346100b8575f3660031901126100b8577f0000000000000000000000001c000000000000000000000000000000000000006001600160a01b03166080908152602090f35b5f80fd5b5f9103126100b857565b346100b8575f3660031901126100b85760206001600160401b0360015416604051908152f35b346100b8575f3660031901126100b8576040517f0000000000000000000000001c000000000000000000000000000000000000036001600160a01b03168152602090f35b346100b8575f3660031901126100b85760205f54604051908152f35b346100b8575f3660031901126100b8576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b9181601f840112156100b8578235916001600160401b0383116100b8576020808501948460051b0101116100b857565b9181601f840112156100b8578235916001600160401b0383116100b85760208085019460c085020101116100b857565b346100b85760803660031901126100b8576004356001600160401b0381116100b857366023820112156100b8578060040135906001600160401b0382116100b85736602483830101116100b8576024356001600160401b0381116100b85761025c903690600401610190565b6044929192356001600160401b0381116100b85761027e9036906004016101c0565b91606435946001600160401b0386116100b8576102ae966102a56024973690600401610190565b979096016109ae565b005b634e487b7160e01b5f52604160045260245ffd5b60a081019081106001600160401b038211176102df57604052565b6102b0565b90601f801991011681019081106001600160401b038211176102df57604052565b6001600160a01b038116036100b857565b908160209103126100b8575161032b81610305565b90565b6040513d5f823e3d90fd5b908060209392818452848401375f828201840152601f01601f1916010190565b91602061032b938181520191610339565b634e487b7160e01b5f52603260045260245ffd5b91908110156103a05760051b81013590607e19813603018212156100b8570190565b61036a565b3561032b81610305565b903590601e19813603018212156100b857018035906001600160401b0382116100b8576020019181360383136100b857565b95939161040d9061041b9461032b99979360018060a01b03168952608060208a01526080890191610339565b918683036040880152610339565b926060818503910152610339565b9492909361044761032b979561045594606089526060890191610339565b918683036020880152610339565b926040818503910152610339565b91908110156103a05760051b81013590603e19813603018212156100b8570190565b6002111561048f57565b634e487b7160e01b5f52602160045260245ffd5b3560028110156100b85790565b35906001600160801b03821682036100b857565b60ff8116036100b857565b6001600160401b0381116102df57601f01601f191660200190565b35906001600160a01b0319821682036100b857565b35906001600160801b0319821682036100b857565b919060a0838203126100b8576040519061052d826102c4565b8193803583526020810135610541816104c4565b602084015260408101356001600160401b0381116100b857810182601f820112156100b857803591610572836104cf565b9361058060405195866102e4565b838552602084840101116100b8576080935f6020856105c19682899701838601378301015260408601526105b6606082016104ea565b6060860152016104ff565b910152565b6020818303126100b8578035906001600160401b0382116100b8570160a0818303126100b857604051916105f9836102c4565b813561060481610305565b8352602082013561061481610305565b6020840152610625604083016104b0565b60408401526060820135606084015260808201356001600160401b0381116100b8576106519201610514565b608082015290565b634e487b7160e01b5f52601160045260245ffd5b5f19811461067b5760010190565b610659565b91908110156103a05760c0020190565b3561032b816104c4565b519081151582036100b857565b908160209103126100b85761032b9061069a565b604051906106ca6040836102e4565b600d82526c65636965732d6165732d6b657960981b6020830152565b91906040838203126100b85782516001600160401b0381116100b857830181601f820112156100b85780519161071b836104cf565b9061072960405192836102e4565b838252602084840101116100b8575f60208461032b95828096018386015e83010152930161069a565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b926107ac9060809360209397969786526bffffffffffffffffffffffff60a01b168386015260a0604086015260a0850190610752565b83810360608501525f815201936001600160801b031916910152565b90600282101561048f5752565b92919060806040916107e88660016107c8565b6060602087015260018060a01b03815116606087015260018060a01b03602082015116828701526001600160801b03838201511660a0870152606081015160c0870152015160a060e0860152805161010086015260ff6020820151166101208601526108648282015160a06101408801526101a0870190610752565b60608201516001600160a01b0319166101608701526080909101516001600160801b031916610180860152930152565b908160a09103126100b8576080604051916108ae836102c4565b80356108b981610305565b835260208101356108c981610305565b602084015260408101356108dc81610305565b60408401526108ed606082016104b0565b60608401520135608082015290565b60c09093929193608060e0820195610914835f6107c8565b80516001600160a01b039081166020858101919091528201518116604080860191909152820151166060808501919091528101516001600160801b031682840152015160a08201520152565b908160209103126100b8575190565b906001600160401b03809116911601906001600160401b03821161067b57565b908160209103126100b857516001600160401b03811681036100b85790565b9591949392969033151580611499575b61148a577f0000000000000000000000001c000000000000000000000000000000000000006001600160a01b031696873b156100b85760405163fe77009960e01b8152915f9183918291610a16919060048401610359565b0381838b5af18015610bde57611476575b505f9492945b81811061135b575050505f54925f915f915b878310610c445750505003610c35576040516381e3da6b60e01b81527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166004808301919091526024820152602081604481865afa8015610bde57610c18575b50805f55610aee610ad26001600160401b038516610acd6001546001600160401b031690565b61096f565b6001600160401b03166001600160401b03196001541617600155565b604051631014997960e31b815291602083600481845afa928315610bde575f93610be3575b50602060049160405192838092631d04645f60e01b82525afa8015610bde577fd2d2bf1e295f62cd08f0f0ab45818efeaba78b58310526f7b7e9686b8aeded1a926001600160401b03925f92610ba9575b50610ba490610b7b6001546001600160401b031690565b6040805198895260208901929092526001600160401b0316908701529116939081906060820190565b0390a3565b610ba4919250610bd09060203d602011610bd7575b610bc881836102e4565b81019061098f565b9190610b64565b503d610bbe565b61032e565b6004919350610c09602091823d8411610c11575b610c0181836102e4565b810190610960565b939150610b13565b503d610bf7565b610c309060203d602011610c1157610c0181836102e4565b610aa7565b6361aba18160e11b5f5260045ffd5b909194610c52868985610463565b610c5b816104a3565b610c6481610485565b610e1957610c79816020610c819301906103af565b810190610894565b90604051610ca681610c98602082019486866108fc565b03601f1981018352826102e4565b5190208151909690610cce90610cc2906001600160a01b031681565b6001600160a01b031690565b6040830180519091906001600160a01b0316906060850191610cf783516001600160801b031690565b823b156100b8576040516340c10f1960e01b81526001600160a01b039290921660048301526001600160801b03166024820152905f908290604490829084905af18015610bde576001958b927fd5277bc9597c7da3fab9cdbba4de6005f48b9eb7389cf2389c4ea9eea3172c2192610dff575b506020810151610d8b906001600160a01b031695516001600160a01b031690565b8151610df390608090610db0906001600160a01b03165b97516001600160801b031690565b930151604080516001600160a01b0390981688526001600160801b0390941660208801529286019290925260a088901b8890039081169516939081906060820190565b0390a45b019190610a3f565b80610e0d5f610e13936102e4565b806100bc565b5f610d6a565b610e2d816020610e359399949901906103af565b8101906105c6565b908585101561134c57610e52610e4a8661066d565b958785610680565b60608301610e608151611559565b9160808601926020608086610ee68751610e7f85825192015160ff1690565b95833598610e8e878601610690565b604051635f8a996960e01b8152600481019490945260ff9889166024850152604484018b905288166064840152608483015290951660a48601529101803560c48501526020013560e484015282908190610104820190565b0381731c000000000000000000000000000000000001005afa908115610bde575f9161131e575b501561130f57518251516040516bffffffffffffffffffffffff197f000000000000000000000000000000000000000000000000000000000000000060601b166020820152603481019290925260548083019190915281525f91610f859190610f776074836102e4565b610f7f6106bb565b906116ca565b915160608101519092906001600160a01b03191690610fd2610fb7608060408701519601516001600160801b03191690565b60405163f4a7eb1360e01b8152958694859460048601610776565b0381731c000000000000000000000000000000000001015afa8015610bde575f915f916112eb575b50806112e0575b156112d85761100f90611736565b9061101f610cc2604085016103a5565b6001600160a01b039091161490816112ca575b50975b60405161104b81610c98602082019488866107d5565b519020976111855750815161106a90610cc2906001600160a01b031681565b602083018051909391906001600160a01b031691604081019261109484516001600160801b031690565b833b156100b8576040516340c10f1960e01b81526001600160a01b039290921660048301526001600160801b03166024820152915f908390604490829084905af1908115610bde5761113b61112d61111f6001988e967f95705d99ac13cf82894fd274cd871942e6f301c98c186271337e8fedbbb9d7ea96611171575b50516001600160a01b031690565b92516001600160a01b031690565b94516001600160801b031690565b604080516001600160a01b039690961686526001600160801b0391909116602086015260a087901b8790039190911693a3610df7565b80610e0d5f61117f936102e4565b5f611111565b825161119b90610cc2906001600160a01b031681565b9060408101916111aa836103a5565b9160408601926111c184516001600160801b031690565b833b156100b8576040516340c10f1960e01b81526001600160a01b039290921660048301526001600160801b03166024820152915f908390604490829084905af1908115610bde576001968c937ffc236d1b4402e76c2b0a882db36ad3a6fb0f5b6b7edc8ae317d993f10434c436936112b6575b506112ae606061126b610da261125d611257602087015160018060a01b031690565b9a6103a5565b94516001600160a01b031690565b604080516001600160a01b0390991689526001600160801b0390911660208901529301359286019290925260a088901b8890039081169516939081906060820190565b0390a4610df7565b80610e0d5f6112c4936102e4565b5f611235565b90506060820135145f611032565b505f97611035565b506040815114611001565b905061130991503d805f833e61130181836102e4565b8101906106e6565b5f610ffa565b63fb1f4a4960e01b5f5260045ffd5b61133f915060203d8111611345575b61133781836102e4565b8101906106a7565b5f610f0d565b503d61132d565b6351de8c1f60e01b5f5260045ffd5b61136981838598969861037e565b90611373826103a5565b91602081019061138382826103af565b9092604083019361139485856103af565b91909760608601986113a68a886103af565b9061083f60921b3b156100b8575f956113d493604051998a9788976374ae5b3760e11b8952600489016103e1565b03818361083f60921b5af18015610bde576001967f4ac4dcc08b0c26c3fb6b58c64c1392b7934b1ce6b0382a5986ea5c3de795e053946114379461145693611462575b5061143f61142e611427836103a5565b95836103af565b969098836103af565b9390926103af565b9290916040519687968c8060a01b03169987610429565b0390a201949294610a2d565b80610e0d5f611470936102e4565b5f611417565b80610e0d5f611484936102e4565b5f610a27565b63bb62587160e01b5f5260045ffd5b50604051630b83774760e31b81526020816004817f0000000000000000000000001c000000000000000000000000000000000000036001600160a01b03165afa908115610bde575f916114f9575b506001600160a01b03163314156109be565b61151b915060203d602011611521575b61151381836102e4565b810190610316565b5f6114e7565b503d611509565b908160011b918083046002149015171561067b57565b906001820180921161067b57565b9190820180921161067b57565b61158a90611584604051602081019061157b81610c9884906006602083019252565b51902091611528565b9061154c565b906116136115978361153e565b6040516381e3da6b60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000818116600484015260248301969096527f0000000000000000000000001c0000000000000000000000000000000000000016949092909190602090849081906044820190565b0381885afa928315610bde575f93611697575b50821561130f576040516381e3da6b60e01b81526001600160a01b03929092166004830152602482015292602090849060449082905afa928315610bde575f93611673575b509160ff1690565b60ff9193506116909060203d602011610c1157610c0181836102e4565b929061166b565b6116b191935060203d602011610c1157610c0181836102e4565b915f611626565b805191908290602001825e015f815290565b9161171e60016116f861032b9561170995604051916020830152602082526116f36040836102e4565b61177f565b9260405194859160208301906116b8565b8260f81b815203601e198101855201836102e4565b604051906020820152602081526116f36040826102e4565b9081516040810361175257506034602083015160601c92015190565b633fbbeba160e21b5f52600452604060245260445ffd5b61032b93926040928252602082015201906116b8565b5f908051604081115f1461188b57505f6117a1602092604051918280926116b8565b039060025afa15610bde5760205f61181c610c986118108351965b6040519283917f363636363636363636363636363636363636363636363636363636363636363689187f36363636363636363636363636363636363636363636363636363636363636368b18898501611769565b604051918280926116b8565b039060025afa15610bde5761187b7f5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c6118105f93610c986020968651908560405196879518911889850191606093918352602083015260408201520190565b039060025afa15610bde575f5190565b60208083015194908211935091600184146118fa57505f925b602082106118e4575b60408210166118ca575b505f61181c610c986118106020946117bc565b600160409190910360031b1b5f190119909116905f6118b7565b935f1960018360200360031b1b011916936118ad565b60400151926118a456fea2646970667358221220f16dbd2f7da7fd90e61eb54c05c7184cb79b274f442504ec67305348da4ca56a64736f6c63430008210033" + "code": "0x60806040526004361015610011575f80fd5b5f3560e01c80631fbb25ad146100745780632d4884821461006f57806379502c551461006a57806382648c3b1461006557806397cac0fb146100605763a21de6d91461005b575f80fd5b61026c565b6101ac565b610130565b6100ec565b6100c6565b346100b8575f3660031901126100b8577f0000000000000000000000001c000000000000000000000000000000000000006001600160a01b03166080908152602090f35b5f80fd5b5f9103126100b857565b346100b8575f3660031901126100b85760206001600160401b0360015416604051908152f35b346100b8575f3660031901126100b8576040517f0000000000000000000000001c000000000000000000000000000000000000036001600160a01b03168152602090f35b346100b8575f3660031901126100b85760205f54604051908152f35b9181601f840112156100b8578235916001600160401b0383116100b8576020808501948460051b0101116100b857565b9181601f840112156100b8578235916001600160401b0383116100b8576020808501948460071b0101116100b857565b346100b85760803660031901126100b8576004356001600160401b0381116100b857366023820112156100b8578060040135906001600160401b0382116100b85736602483830101116100b8576024356001600160401b0381116100b85761021890369060040161014c565b6044929192356001600160401b0381116100b85761023a90369060040161017c565b91606435946001600160401b0386116100b85761026a96610261602497369060040161014c565b979096016109d1565b005b346100b8575f3660031901126100b8576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b634e487b7160e01b5f52604160045260245ffd5b60a081019081106001600160401b038211176102df57604052565b6102b0565b90601f801991011681019081106001600160401b038211176102df57604052565b6001600160a01b038116036100b857565b908160209103126100b8575161032b81610305565b90565b6040513d5f823e3d90fd5b908060209392818452848401375f828201840152601f01601f1916010190565b91602061032b938181520191610339565b634e487b7160e01b5f52603260045260245ffd5b91908110156103a05760051b81013590607e19813603018212156100b8570190565b61036a565b3561032b81610305565b903590601e19813603018212156100b857018035906001600160401b0382116100b8576020019181360383136100b857565b95939161040d9061041b9461032b99979360018060a01b03168952608060208a01526080890191610339565b918683036040880152610339565b926060818503910152610339565b9492909361044761032b979561045594606089526060890191610339565b918683036020880152610339565b926040818503910152610339565b91908110156103a05760051b81013590603e19813603018212156100b8570190565b6002111561048f57565b634e487b7160e01b5f52602160045260245ffd5b3560028110156100b85790565b35906001600160801b03821682036100b857565b60ff8116036100b857565b6001600160401b0381116102df57601f01601f191660200190565b35906001600160a01b0319821682036100b857565b35906001600160801b0319821682036100b857565b919060a0838203126100b8576040519061052d826102c4565b8193803583526020810135610541816104c4565b602084015260408101356001600160401b0381116100b857810182601f820112156100b857803591610572836104cf565b9361058060405195866102e4565b838552602084840101116100b8576080935f6020856105c19682899701838601378301015260408601526105b6606082016104ea565b6060860152016104ff565b910152565b6020818303126100b8578035906001600160401b0382116100b8570160a0818303126100b857604051916105f9836102c4565b813561060481610305565b8352602082013561061481610305565b6020840152610625604083016104b0565b60408401526060820135606084015260808201356001600160401b0381116100b8576106519201610514565b608082015290565b634e487b7160e01b5f52601160045260245ffd5b5f19811461067b5760010190565b610659565b91908110156103a05760071b0190565b3561032b816104c4565b519081151582036100b857565b908160209103126100b85761032b9061069a565b604051906106ca6040836102e4565b600d82526c65636965732d6165732d6b657960981b6020830152565b91906040838203126100b85782516001600160401b0381116100b857830181601f820112156100b85780519161071b836104cf565b9061072960405192836102e4565b838252602084840101116100b8575f60208461032b95828096018386015e83010152930161069a565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b926107ac9060809360209397969786526bffffffffffffffffffffffff60a01b168386015260a0604086015260a0850190610752565b83810360608501525f815201936001600160801b031916910152565b90600282101561048f5752565b92919060806040916107e88660016107c8565b6060602087015260018060a01b03815116606087015260018060a01b03602082015116828701526001600160801b03838201511660a0870152606081015160c0870152015160a060e0860152805161010086015260ff6020820151166101208601526108648282015160a06101408801526101a0870190610752565b60608201516001600160a01b0319166101608701526080909101516001600160801b031916610180860152930152565b6001600160a01b0390911681526001600160801b03909116602082015260400190565b908160a09103126100b8576080604051916108d1836102c4565b80356108dc81610305565b835260208101356108ec81610305565b602084015260408101356108ff81610305565b6040840152610910606082016104b0565b60608401520135608082015290565b60c09093929193608060e0820195610937835f6107c8565b80516001600160a01b039081166020858101919091528201518116604080860191909152820151166060808501919091528101516001600160801b031682840152015160a08201520152565b908160209103126100b8575190565b906001600160401b03809116911601906001600160401b03821161067b57565b908160209103126100b857516001600160401b03811681036100b85790565b9591949392969033151580611482575b611473577f0000000000000000000000001c000000000000000000000000000000000000006001600160a01b031696873b156100b85760405163fe77009960e01b8152915f9183918291610a39919060048401610359565b0381838b5af18015610c015761145f575b505f9492945b818110611344575050505f54925f915f915b878310610c675750505003610c58576040516381e3da6b60e01b81527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166004808301919091526024820152602081604481865afa8015610c0157610c3b575b50805f55610b11610af56001600160401b038516610af06001546001600160401b031690565b610992565b6001600160401b03166001600160401b03196001541617600155565b604051631014997960e31b815291602083600481845afa928315610c01575f93610c06575b50602060049160405192838092631d04645f60e01b82525afa8015610c01577fd2d2bf1e295f62cd08f0f0ab45818efeaba78b58310526f7b7e9686b8aeded1a926001600160401b03925f92610bcc575b50610bc790610b9e6001546001600160401b031690565b6040805198895260208901929092526001600160401b0316908701529116939081906060820190565b0390a3565b610bc7919250610bf39060203d602011610bfa575b610beb81836102e4565b8101906109b2565b9190610b87565b503d610be1565b61032e565b6004919350610c2c602091823d8411610c34575b610c2481836102e4565b810190610983565b939150610b36565b503d610c1a565b610c539060203d602011610c3457610c2481836102e4565b610aca565b6361aba18160e11b5f5260045ffd5b909194610c75868985610463565b610c7e816104a3565b610c8781610485565b610e2857610c9c816020610ca49301906103af565b8101906108b7565b90604051610cc981610cbb6020820194868661091f565b03601f1981018352826102e4565b5190208151909690610cf190610ce5906001600160a01b031681565b6001600160a01b031690565b6040830180519091906001600160a01b0316906060850191610d1a83516001600160801b031690565b823b156100b857610d44925f92836040518096819582946340c10f1960e01b845260048401610894565b03925af18015610c01576001958b927fd5277bc9597c7da3fab9cdbba4de6005f48b9eb7389cf2389c4ea9eea3172c2192610e0e575b506020810151610d9b906001600160a01b031695516001600160a01b031690565b8151610e0290608090610dbf906001600160a01b031697516001600160801b031690565b930151604080516001600160a01b0390981688526001600160801b0390941660208801529286019290925260a088901b8890039081169516939081906060820190565b0390a45b019190610a62565b80610e1c5f610e22936102e4565b806100bc565b5f610d7a565b610e3c816020610e449399949901906103af565b8101906105c6565b908585101561133557610ef696610e65610e5d8761066d565b968886610680565b6060840160406020610e778351611542565b929094608089019d8e51610e9085825192015160ff1690565b95833598610e9f878601610690565b8651635f8a996960e01b8152600481019490945260ff9889166024850152604484018b905288166064840152608483015290951660a48601529101803560c48501526020013560e484015282908190610104820190565b0381731c000000000000000000000000000000000001005afa908115610c01575f91611307575b50156112f857518951516040516bffffffffffffffffffffffff197f000000000000000000000000000000000000000000000000000000000000000060601b166020820152603481019290925260548083019190915281525f91610f959190610f876074836102e4565b610f8f6106bb565b906116b3565b98518099610fed610fd260806040610fbf60608701516bffffffffffffffffffffffff60a01b1690565b9501519d01516001600160801b03191690565b60405163f4a7eb1360e01b81529c8d94859460048601610776565b0381731c000000000000000000000000000000000001015afa978815610c01575f905f996112d1575b505f808a806112c6575b156112ba5750506110309061171f565b90915b60405161104981610cbb602082019489866107d5565b5190209861115b575050815161106990610ce5906001600160a01b031681565b602083018051909391906001600160a01b031691604081019261109384516001600160801b031690565b833b156100b8576110bd935f92836040518097819582946340c10f1960e01b845260048401610894565b03925af1908115610c015761112761111961110b6001988e967f95705d99ac13cf82894fd274cd871942e6f301c98c186271337e8fedbbb9d7ea96611147575b50516001600160a01b031690565b92516001600160a01b031690565b94516001600160801b031690565b9061113f604051928392898060a01b03169683610894565b0390a3610e06565b80610e1c5f611155936102e4565b5f6110fd565b835161117190610ce5906001600160a01b031681565b90604085019261118884516001600160801b031690565b833b156100b8575f6111b48d9582936040519485809481936340c10f1960e01b83528960048401610894565b03925af190816112a6575b506111ff57505083516111dd9150610ce5906001600160a01b031681565b6020840180519094906001600160a01b031683516001600160801b0316611093565b859392917ffc236d1b4402e76c2b0a882db36ad3a6fb0f5b6b7edc8ae317d993f10434c4369161129e61125f611251611243602060019c015160018060a01b031690565b98516001600160a01b031690565b96516001600160801b031690565b604080516001600160a01b0390981688526001600160801b03909116602088015286019290925260a088901b8890039081169516939081906060820190565b0390a4610e06565b80610e1c5f6112b4936102e4565b5f6111bf565b91509198505f98611033565b506040835114611020565b90506112f09198503d805f833e6112e881836102e4565b8101906106e6565b97905f611016565b63fb1f4a4960e01b5f5260045ffd5b611328915060203d811161132e575b61132081836102e4565b8101906106a7565b5f610f1d565b503d611316565b6351de8c1f60e01b5f5260045ffd5b61135281838598969861037e565b9061135c826103a5565b91602081019061136c82826103af565b9092604083019361137d85856103af565b919097606086019861138f8a886103af565b9061083f60921b3b156100b8575f956113bd93604051998a9788976374ae5b3760e11b8952600489016103e1565b03818361083f60921b5af18015610c01576001967f4ac4dcc08b0c26c3fb6b58c64c1392b7934b1ce6b0382a5986ea5c3de795e053946114209461143f9361144b575b50611428611417611410836103a5565b95836103af565b969098836103af565b9390926103af565b9290916040519687968c8060a01b03169987610429565b0390a201949294610a50565b80610e1c5f611459936102e4565b5f611400565b80610e1c5f61146d936102e4565b5f610a4a565b63bb62587160e01b5f5260045ffd5b50604051630b83774760e31b81526020816004817f0000000000000000000000001c000000000000000000000000000000000000036001600160a01b03165afa908115610c01575f916114e2575b506001600160a01b03163314156109e1565b611504915060203d60201161150a575b6114fc81836102e4565b810190610316565b5f6114d0565b503d6114f2565b908160011b918083046002149015171561067b57565b906001820180921161067b57565b9190820180921161067b57565b6115739061156d604051602081019061156481610cbb84906006602083019252565b51902091611511565b90611535565b906115fc61158083611527565b6040516381e3da6b60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000818116600484015260248301969096527f0000000000000000000000001c0000000000000000000000000000000000000016949092909190602090849081906044820190565b0381885afa928315610c01575f93611680575b5082156112f8576040516381e3da6b60e01b81526001600160a01b03929092166004830152602482015292602090849060449082905afa928315610c01575f9361165c575b509160ff1690565b60ff9193506116799060203d602011610c3457610c2481836102e4565b9290611654565b61169a91935060203d602011610c3457610c2481836102e4565b915f61160f565b805191908290602001825e015f815290565b9161170760016116e161032b956116f295604051916020830152602082526116dc6040836102e4565b611768565b9260405194859160208301906116a1565b8260f81b815203601e198101855201836102e4565b604051906020820152602081526116dc6040826102e4565b9081516040810361173b57506034602083015160601c92015190565b633fbbeba160e21b5f52600452604060245260445ffd5b61032b93926040928252602082015201906116a1565b5f908051604081115f1461187457505f61178a602092604051918280926116a1565b039060025afa15610c015760205f611805610cbb6117f98351965b6040519283917f363636363636363636363636363636363636363636363636363636363636363689187f36363636363636363636363636363636363636363636363636363636363636368b18898501611752565b604051918280926116a1565b039060025afa15610c01576118647f5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c6117f95f93610cbb6020968651908560405196879518911889850191606093918352602083015260408201520190565b039060025afa15610c01575f5190565b60208083015194908211935091600184146118e357505f925b602082106118cd575b60408210166118b3575b505f611805610cbb6117f96020946117a5565b600160409190910360031b1b5f190119909116905f6118a0565b935f1960018360200360031b1b01191693611896565b604001519261188d56fea26469706673582212208e93ef9bfe51376039a34783438753d575cafb9c32630db748d87afe43a51c4a64736f6c634300081e0033" }, "0x1c00000000000000000000000000000000000002": { "nonce": "0x1", "balance": "0x0", - "code": "0x6080806040526004361015610012575f80fd5b5f3560e01c9081632c37826e14610776575080633406527214610751578063378fa8fa1461073657806343c3cb831461071b57806344ee09321461069157806348aa41081461063757806353a8d7391461061b578063545525f1146105fe57806379502c55146105ba57806379fa3289146104ae5780637b9c9aa41461046e578063a94cd931146103eb578063b3b200aa14610347578063b79a6c0c1461024c578063bba9282e14610224578063c9b6ca9b14610208578063ce7025e914610135578063d93af1d2146101135763f490ca96146100ed575f80fd5b3461010f575f36600319011261010f576020604051670de0b6b3a76400008152f35b5f80fd5b3461010f575f36600319011261010f57602061012d610990565b604051908152f35b3461010f57606036600319011261010f5761014e610792565b604435906001600160401b03821161010f573660238301121561010f578160040135916001600160401b03831161010f5760248360051b82010136811161010f57610198846108d0565b936101a660405195866108af565b84526024820191602085015b8284106101c857602061012d8787600435610b47565b83356001600160401b03811161010f5782013660438201121561010f576020916101fd8392369060446024820135910161094b565b8152019301926101b2565b3461010f575f36600319011261010f57602060405161c3508152f35b3461010f575f36600319011261010f5760206001600160401b035f5460801c16604051908152f35b3461010f57602036600319011261010f57600435331515806102ad575b61029e576020817f4f0c4dec68e1e774843a5fc3a522ab2a832ecfc975b9ad8a5033736d9e47f09d92600555604051908152a1005b63bb62587160e01b5f5260045ffd5b50604051630b83774760e31b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561033c575f9161030d575b506001600160a01b0316331415610269565b61032f915060203d602011610335575b61032781836108af565b8101906108e7565b826102fb565b503d61031d565b6040513d5f823e3d90fd5b3461010f5761010036600319011261010f576103616107d4565b6103696107ea565b6103716107be565b6103796107a8565b610381610800565b9060c4356001600160401b03811161010f576103a1903690600401610816565b95909360e4356001600160401b03811161010f576103e9976103d76103cd6103df933690600401610816565b989092369161094b565b96369161094b565b95606435926111e6565b005b3461010f5760e036600319011261010f576104046107d4565b61040c6107ea565b6104146107be565b61041c6107a8565b610424610800565b9060c435946001600160401b03861161010f5761045261044b6103e9973690600401610816565b369161094b565b93604051956104626020886108af565b5f8752606435926111e6565b3461010f57602036600319011261010f576004356001600160401b038116810361010f5761049d602091610906565b6001600160801b0360405191168152f35b3461010f57602036600319011261010f576004356001600160801b03811680910361010f573315158061053b575b61029e57670de0b6b3a7640000811161052c576020817f6f864cce5237e12ffc9a99fc6c59af17222c2bbb3457690cc8753ab16b5d715e926001600160801b03195f5416175f55604051908152a1005b630d62f21160e11b5f5260045ffd5b50604051630b83774760e31b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561033c575f9161059b575b506001600160a01b03163314156104dc565b6105b4915060203d6020116103355761032781836108af565b82610589565b3461010f575f36600319011261010f576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461010f575f36600319011261010f576020600554604051908152f35b3461010f575f36600319011261010f5760206040516104008152f35b3461010f575f36600319011261010f575f602060405161065681610864565b82815201526040805161066881610864565b6001600160401b0360015491828152602082600254169101908152835192835251166020820152f35b3461010f57604036600319011261010f5760206004356106af610792565b816106bf60035460045490610843565b809111610713575b506106d1826108d0565b906106df60405192836108af565b828252601f196106ee846108d0565b01925f5b848110610704575061012d9350610b47565b606084820187015285016106f2565b9150836106c7565b3461010f575f36600319011261010f57602060405160718152f35b3461010f575f36600319011261010f57602060405160218152f35b3461010f575f36600319011261010f5760206001600160801b035f5416604051908152f35b3461010f575f36600319011261010f576020905f5460c01c8152f35b602435906001600160401b038216820361010f57565b608435906001600160401b038216820361010f57565b604435906001600160801b038216820361010f57565b600435906001600160a01b038216820361010f57565b602435906001600160a01b038216820361010f57565b60a435906001600160a01b038216820361010f57565b9181601f8401121561010f578235916001600160401b03831161010f576020838186019501011161010f57565b9190820391821161085057565b634e487b7160e01b5f52601160045260245ffd5b604081019081106001600160401b0382111761087f57604052565b634e487b7160e01b5f52604160045260245ffd5b61016081019081106001600160401b0382111761087f57604052565b90601f801991011681019081106001600160401b0382111761087f57604052565b6001600160401b03811161087f5760051b60200190565b9081602091031261010f57516001600160a01b038116810361010f5790565b6001600160401b031661c350016001600160401b038111610850576001600160401b036001600160801b035f54169116026001600160801b0381169081036108505790565b9291926001600160401b03821161087f5760405191610974601f8201601f1916602001846108af565b82948184528183011161010f578281602093845f960137010152565b60045460035490818110156109ab576109a891610843565b90565b50505f90565b6003548110156109cd5760035f52600960205f20910201905f90565b634e487b7160e01b5f52603260045260245ffd5b90600182811c92168015610a0f575b60208310146109fb57565b634e487b7160e01b5f52602260045260245ffd5b91607f16916109f0565b9060405191825f825492610a2c846109e1565b8084529360018116908115610a975750600114610a53575b50610a51925003836108af565b565b90505f9291925260205f20905f915b818310610a7b575050906020610a51928201015f610a44565b6020919350806001915483858901015201910190918492610a62565b905060209250610a5194915060ff191682840152151560051b8201015f610a44565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b5f5b828110610aeb57505050565b5f82820155600101610adf565b610b0281546109e1565b9081610b0c575050565b81601f5f9311600114610b1d575055565b81835260208320610b3a91601f0160051c84190190600101610add565b8082528160208120915555565b9092915f9333151580611167575b61029e576001600160401b0380431691160361115857600354610b7b6004548092610843565b808411611150575b508151838103611139575082610c2a575b5050505f5460018160c01c01906001600160401b038211610850576001600160c01b031660c091821b6001600160c01b031916175f81905560405184927fec4aff46c65f485f4b15e3c2edadda1d57d002995f5aa262a27c76b9a680ec1692602092911c9081908390610c0681610864565b868152015283600155806001600160401b03196002541617600255604051908152a2565b5f1994509182019190828211610850579082915b818311610df65750505080600455600354809114610c5e575b8080610b94565b5f60035580610c73575b505f6004555f610c57565b806009029060098204036108505760035f525f5b818110610c945750610c68565b6009905f817fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01555f7fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c8201555f7fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85d8201555f7fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85e8201555f7fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85f8201555f7fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f8608201555f7fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f861820155610dc57fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f8628201610af8565b610df07fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f8638201610af8565b01610c87565b9091945f19860195861161085057610e0d866109b1565b5060405190610e1b82610893565b60018060a01b03815416825260018060a01b036001820154169260208301938452886002830154936040810194855260018060a01b0360038501541693606082019485526004810154918960808201976001600160801b038516895260a083019460801c855260058401549060c08401918252600685015493610eea60e08201946001600160401b038716865261010083019660018060a01b039060401c168752610edc6008610ecd60078b01610a19565b9961012086019a8b5201610a19565b9961014084019a8b52610843565b8d518110156109cd5760051b8d0160200151975151611132575f5b885181810361111d5750506001600160801b036001600160401b0392819260018060a01b039051169d5190516040519060208201926bffffffffffffffffffffffff199060601b168352603482015260348152610f636054826108af565b5190209a60018060a01b039051169b511696511691519251169260018060a01b039051169351946040519a6101408c018c81106001600160401b0382111761087f576040528b5260208b0198895260408b01998a5260608b0190815260808b0191825260a08b0192835260c08b0193845260e08b019485526101008b019586526101208b01968752604051998a9960208b019c60408e52600160a01b6001900390511660608c01525160808b0152600160a01b6001900390511660a08a0152516001600160801b031660c0890152516001600160801b031660e088015251610100870152516001600160401b0316610120860152600160a01b6001900390511661014085015251610160840161014090526101a0840161108291610ab9565b9051838203605f190161018085015261109b9190610ab9565b90604083015203601f19810182526110b390826108af565b519020946110c0816109b1565b61110a576008815f61110393555f60018201555f60028201555f60038201555f60048201555f60058201555f60068201556110fd60078201610af8565b01610af8565b9190610c3e565b634e487b7160e01b5f525f60045260245ffd5b63521a2d4d60e11b5f5260045260245260445ffd5b6071610f05565b8390630db2128560e11b5f5260045260245260445ffd5b92505f610b83565b631391e11b60e21b5f5260045ffd5b50604051630b83774760e31b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561033c575f916111c7575b506001600160a01b0316331415610b55565b6111e0915060203d6020116103355761032781836108af565b5f6111b5565b5f969195909491936001600160a01b0390911692831561189c5761040085511161188d57611213896118ab565b60055480611848575b506001600160801b038061122f85610906565b92169116908181016001600160801b0381116108505760405163868a2e9d60e01b8152946020866004815f60056007609a1b015af195861561033c575f96611814575b508515611805576040516323b872dd60e01b81523360048201523060248201526001600160801b0392909216604483018190526001600160a01b0390991698916020816064815f8e5af190811561033c575f916117ca575b50156117bb57883b1561010f5760405191630852cd8d60e31b835260048301525f82602481838d5af191821561033c578c926117a4575b50876040519161131083610893565b8a8352886020840198338a5260408501908152606085019d60018060a01b03169d8e8152608086019088825260a08701908a825260c08801938c85526001600160401b0360e08a0197169d8e88526101008a019687526101208a019889526101408a019a8b526003546801000000000000000081101561178a5780600161139a92016003556109b1565b9a909a61177157518a546001600160a01b03199081166001600160a01b03928316178c55915160018c0180548416918316919091179055915160028b0155915160038a01805490931691161790559051905160801b6fffffffffffffffffffffffffffffffff19166001600160801b0391909116176004860155516005850155905160068401805492516001600160e01b03199093166001600160401b039283161760409390931b68010000000000000000600160e01b031692909217909155905180516007840192909190821161175d578d9061147884546109e1565b601f811161171a575b50602091601f84116001146116b45760089594936114b5939092836115e7575b50508160011b915f199060031b1c19161790565b90555b01905180516001600160401b0381116116a0578b6114d684546109e1565b601f8111611654575b505060208c601f83116001146115f2579061150d93836115e75750508160011b915f199060031b1c19161790565b90555b8854986001600160401b038a60801c16996001600160401b038b146115d357926115be95927f348c28d1410ff29393c038fe0f1998384082e98e315624b24c04a4fa6288b9de9a999895926115ce98958d60016001600160401b0360801b910160801b16906001600160401b0360801b1916179055604051998a998a5260208a015260408901526060880152608087015260a086015260c085015261012060e0850152610120840190610ab9565b8281036101008401523396610ab9565b0390a3565b634e487b7160e01b82526011600452602482fd5b015190505f806114a1565b9192601f198416858452828420935b81811061163c5750908460019594939210611624575b505050811b019055611510565b01515f1960f88460031b161c191690555f8080611617565b92936020600181928786015181550195019301611601565b84838211611663575b506114df565b61169092528d6020812091601f850160051c9160208610611698575b50601f82910160051c039101610add565b8b5f8461165d565b91508f61167f565b634e487b7160e01b8c52604160045260248cfd5b9190601f198416858452828420935b8181106117025750916001939185600898979694106116ea575b505050811b0190556114b8565b01515f1960f88460031b161c191690555f80806116dd565b929360206001819287860151815501950193016116c3565b838111156114815761174f908584526020842090601f860160051c9060208710611755575b601f82910160051c039101610add565b5f611481565b85915061173f565b634e487b7160e01b8e52604160045260248efd5b50505050505060248f634e487b7160e01b815280600452fd5b50505050505060248f634e487b7160e01b81526041600452fd5b5f919b506117b292506108af565b895f995f611301565b6312171d8360e31b5f5260045ffd5b90506020813d6020116117fd575b816117e5602093836108af565b8101031261010f5751801515810361010f575f6112ca565b3d91506117d8565b632968ee7f60e21b5f5260045ffd5b9095506020813d602011611840575b81611830602093836108af565b8101031261010f5751945f611272565b3d9150611823565b6007544303611880575b60065490811015611871575f198114610850576001016006555f61121c565b63124ab48560e11b5f5260045ffd5b436007555f600655611852565b634b8a874d60e11b5f5260045ffd5b63c29f0c7160e01b5f5260045ffd5b80518015611903576021036118e5578051156109cd57602001516001600160f81b031916600160f91b81141590816118f4575b506118e557565b6361d0136b60e11b5f5260045ffd5b600360f81b141590505f6118de565b505056fea2646970667358221220652e7449c8658b6fc3b3333b742e8b3959d13566217fc352249d4a8ad22860c164736f6c63430008220033" + "code": "0x60806040526004361015610011575f80fd5b5f3560e01c80632c37826e14610134578063340652721461012f578063378fa8fa1461012a57806343c3cb831461012557806348aa41081461012057806353a8d7391461011b578063545525f11461011657806379502c551461011157806379fa32891461010c5780637b9c9aa414610107578063a94cd93114610102578063b3b200aa146100fd578063b79a6c0c146100f8578063bba9282e146100f3578063c9b6ca9b146100ee578063ce7025e9146100e9578063d93af1d2146100e45763f490ca96146100df575f80fd5b6107a7565b610785565b61070c565b6106f0565b6106c8565b6105ea565b610552565b6104c0565b610442565b6102c4565b610254565b610237565b61021b565b6101c1565b6101a6565b61018b565b610166565b610147565b5f91031261014357565b5f80fd5b34610143575f3660031901126101435760205f5460c01c604051908152f35b34610143575f3660031901126101435760206001600160801b035f5416604051908152f35b34610143575f36600319011261014357602060405160218152f35b34610143575f36600319011261014357602060405160718152f35b34610143575f366003190112610143575f60206040516101e0816107dd565b8281520152604080516101f2816107dd565b6001600160401b0360015491828152602082600254169101908152835192835251166020820152f35b34610143575f3660031901126101435760206040516104008152f35b34610143575f366003190112610143576020600554604051908152f35b34610143575f366003190112610143576040517f0000000000000000000000001c000000000000000000000000000000000000036001600160a01b03168152602090f35b600435906001600160801b038216820361014357565b604435906001600160801b038216820361014357565b34610143576020366003190112610143576102dd610298565b33151580610382575b61037357670de0b6b3a76400006001600160801b038216116103645761035f816103457f6f864cce5237e12ffc9a99fc6c59af17222c2bbb3457690cc8753ab16b5d715e936001600160801b03166001600160801b03195f5416175f55565b6040516001600160801b0390911681529081906020820190565b0390a1005b630d62f21160e11b5f5260045ffd5b63bb62587160e01b5f5260045ffd5b50604051630b83774760e31b81526020816004817f0000000000000000000000001c000000000000000000000000000000000000036001600160a01b03165afa908115610411575f916103e2575b506001600160a01b03163314156102e6565b610404915060203d60201161040a575b6103fc81836107fd565b81019061084f565b5f6103d0565b503d6103f2565b610867565b608435906001600160401b038216820361014357565b602435906001600160401b038216820361014357565b34610143576020366003190112610143576004356001600160401b0381168103610143576104716020916108a9565b6001600160801b0360405191168152f35b6001600160a01b0381160361014357565b9181601f84011215610143578235916001600160401b038311610143576020838186019501011161014357565b346101435760e0366003190112610143576004356104dd81610482565b602435906104ea82610482565b6104f26102ae565b916064356104fe610416565b60a4359161050b83610482565b60c435956001600160401b03871161014357610538610531610550983690600401610493565b3691610909565b94604051966105486020896107fd565b5f8852610ea3565b005b34610143576101003660031901126101435760043561057081610482565b60243561057c81610482565b6105846102ae565b91606435610590610416565b9060a43561059d81610482565b60c4356001600160401b038111610143576105bc903690600401610493565b93909260e435976001600160401b038911610143576105e2610550993690600401610493565b98909761093f565b346101435760203660031901126101435760043533151580610649575b6103735761035f816106397f4f0c4dec68e1e774843a5fc3a522ab2a832ecfc975b9ad8a5033736d9e47f09d93600555565b6040519081529081906020820190565b50604051630b83774760e31b81526020816004817f0000000000000000000000001c000000000000000000000000000000000000036001600160a01b03165afa908115610411575f916106a9575b506001600160a01b0316331415610607565b6106c2915060203d60201161040a576103fc81836107fd565b5f610697565b34610143575f3660031901126101435760206001600160401b035f5460801c16604051908152f35b34610143575f36600319011261014357602060405161c3508152f35b346101435760603660031901126101435760043561072861042c565b604435916001600160401b0383116101435736602384011215610143578260040135916001600160401b038311610143573660248460051b860101116101435761077b6106399360246107819601610966565b9161159a565b0390f35b34610143575f36600319011261014357602061079f610a03565b604051908152f35b34610143575f366003190112610143576020604051670de0b6b3a76400008152f35b634e487b7160e01b5f52604160045260245ffd5b604081019081106001600160401b038211176107f857604052565b6107c9565b90601f801991011681019081106001600160401b038211176107f857604052565b6040519061082e610160836107fd565b565b6040519061082e610140836107fd565b6040519061082e6040836107fd565b90816020910312610143575161086481610482565b90565b6040513d5f823e3d90fd5b634e487b7160e01b5f52601160045260245ffd5b6001600160401b036001911601906001600160401b0382116108a457565b610872565b6001600160401b031661c350016001600160401b0381116108a4576001600160401b036001600160801b035f54169116026001600160801b0381169081036108a45790565b6001600160401b0381116107f857601f01601f191660200190565b929192610915826108ee565b9161092360405193846107fd565b829481845281830111610143578281602093845f960137010152565b9761095861096092939495969761082e9b993691610909565b973691610909565b96610ea3565b6001600160401b0382116107f8578160051b906040519261098a60208401856107fd565b835260208301918101903682116101435780925b8284106109ac575050505090565b83356001600160401b03811161014357820136601f82011215610143576020916109dd839236908481359101610909565b81520193019261099e565b5f198101919082116108a457565b919082039182116108a457565b6004546003549081811015610a1e5781039081116108a45790565b50505f90565b5f1981146108a45760010190565b906001600160801b03809116911601906001600160801b0382116108a457565b90816020910312610143575190565b90816020910312610143575180151581036101435790565b634e487b7160e01b5f52603260045260245ffd5b600354811015610aa95760035f52600960205f20910201905f90565b610a79565b8054821015610aa9575f52600960205f20910201905f90565b634e487b7160e01b5f525f60045260245ffd5b90600182811c92168015610b08575b6020831014610af457565b634e487b7160e01b5f52602260045260245ffd5b91607f1691610ae9565b818110610b1d575050565b5f8155600101610b12565b9190601f8111610b3757505050565b61082e925f5260205f20906020601f840160051c83019310610b61575b601f0160051c0190610b12565b9091508190610b54565b91909182516001600160401b0381116107f857610b9281610b8c8454610ada565b84610b28565b6020601f8211600114610bd1578190610bc29394955f92610bc6575b50508160011b915f199060031b1c19161790565b9055565b015190505f80610bae565b601f19821690610be4845f5260205f2090565b915f5b818110610c1e57509583600195969710610c06575b505050811b019055565b01515f1960f88460031b161c191690555f8080610bfc565b9192602060018192868b015181550194019201610be7565b600354680100000000000000008110156107f857806001610c5c92016003556003610aae565b610de457815181546001600160a01b0319166001600160a01b0390911617815561082e916008906101409060208101516001850180546001600160a01b0319166001600160a01b039092169190911790556040810151600285015560608101516003850180546001600160a01b0319166001600160a01b03909216919091179055610d4560048501610d17610cfb60808501516001600160801b031690565b82546001600160801b0319166001600160801b03909116178255565b60a08301516001600160801b031681546001600160801b031660809190911b6001600160801b031916179055565b60c08101516005850155610dc960068501610d8a610d6d60e08501516001600160401b031690565b825467ffffffffffffffff19166001600160401b03909116178255565b6101008301516001600160a01b0316815468010000000000000000600160e01b03191660409190911b68010000000000000000600160e01b0316179055565b610ddb61012082015160078601610b6b565b01519101610b6b565b610ac7565b6001600160401b03166001600160401b0381146108a45760010190565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b6001600160a01b03918216815291811660208301526001600160801b03928316604083015292909116606082015260808101929092526001600160401b039290921660a0820152911660c082015261012060e08201819052610864939192610e9491840190610e06565b91610100818403910152610e06565b95969092949693919360018060a01b038816156111bd576104008151116111ae57610ecd8261194f565b60055461115b575b610ede836108a9565b97610ee98987610a32565b60405163868a2e9d60e01b8152979094906020896004815f60056007609a1b015af1988915610411575f9961112a575b50881561111b576040516323b872dd60e01b81523360048201523060248201526001600160801b03871660448201526001600160a01b038b16906020816064815f865af1908115610411575f916110ec575b50156110dd57803b1561014357604051630852cd8d60e31b81526001600160801b039790971660048801525f908790602490829084905af18015610411577f348c28d1410ff29393c038fe0f1998384082e98e315624b24c04a4fa6288b9de996110be9761105f926110c3575b50610fe161081e565b6001600160a01b038d1681529033602083015260408201526001600160a01b03891660608201526001600160801b038a1660808201526001600160801b038d1660a082015260c081018390526001600160401b03841660e08201526001600160a01b0385166101008201528561012082015286610140820152610c36565b5f5460801c6001600160401b03169a6110a661107a8d610de9565b5f805467ffffffffffffffff60801b191660809290921b67ffffffffffffffff60801b16919091179055565b6040519889986001600160401b03339e169c8a610e2a565b0390a3565b806110d15f6110d7936107fd565b80610139565b5f610fd8565b6312171d8360e31b5f5260045ffd5b61110e915060203d602011611114575b61110681836107fd565b810190610a61565b5f610f6b565b503d6110fc565b632968ee7f60e21b5f5260045ffd5b61114d91995060203d602011611154575b61114581836107fd565b810190610a52565b975f610f19565b503d61113b565b6007544303611197575b6006546005548110156111885761117e61118391610a24565b600655565b610ed5565b63124ab48560e11b5f5260045ffd5b6111a043600755565b6111a95f600655565b611165565b634b8a874d60e11b5f5260045ffd5b63c29f0c7160e01b5f5260045ffd5b919082018092116108a457565b9060405191825f8254926111ec84610ada565b80845293600181169081156112555750600114611211575b5061082e925003836107fd565b90505f9291925260205f20905f915b81831061123957505090602061082e928201015f611204565b6020919350806001915483858901015201910190918492611220565b90506020925061082e94915060ff191682840152151560051b8201015f611204565b90611377600861128561081e565b84546001600160a01b031681529360018101546001600160a01b031660208601526002810154604086015260038101546001600160a01b031660608601526113076112f760048301546112f16112e1826001600160801b031690565b6001600160801b031660808a0152565b60801c90565b6001600160801b031660a0870152565b600581015460c086015261135f61134e600683015461133f61132f826001600160401b031690565b6001600160401b031660e08a0152565b60401c6001600160a01b031690565b6001600160a01b0316610100870152565b61136b600782016111d9565b610120860152016111d9565b610140830152565b8051821015610aa95760209160051b010190565b604080825282516001600160a01b0316908201529291906020906114589080830151606087015260408101516001600160a01b0316608087015260608101516001600160801b031660a087015260808101516001600160801b031660c087015260a081015160e087015260c08101516001600160401b031661010087015260e08101516001600160a01b0316610120870152610120611443610100830151610140808a0152610180890190610e06565b910151868203603f1901610160880152610e06565b930152565b6114678154610ada565b9081611471575050565b81601f5f9311600114611482575055565b8183526020832061149e91601f0160051c810190600101610b12565b808252602082209081548360011b9084198560031b1c191617905555565b90610de4576008815f61082e93555f60018201555f60028201555f60038201555f60048201555f60058201555f60068201556114fa6007820161145d565b0161145d565b6003545f6003558061150f5750565b806009029060098204036108a45760035f527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b908101905b818110611552575050565b6009905f81555f60018201555f60028201555f60038201555f60048201555f60058201555f60068201556115886007820161145d565b6115946008820161145d565b01611547565b9092915f93331515806118d0575b610373576001600160401b038043169116036118c157600354906115cf60045480936109f6565b8084116118b9575b5080518381036118a25750826116af575b5050506116256116016115fc5f5460c01c90565b610886565b5f80546001600160c01b031660c09290921b6001600160c01b031916919091179055565b817fec4aff46c65f485f4b15e3c2edadda1d57d002995f5aa262a27c76b9a680ec166116aa6116555f5460c01c90565b611690611660610840565b8581526001600160401b038316602090910181905260018690556002805467ffffffffffffffff19169091179055565b6040516001600160401b0390911681529081906020820190565b0390a2565b5f199450916116be90826111cc565b91825b8281116116f857505050600455600454600354146116e2575b5f80806115e8565b6116ea611500565b6116f35f600455565b6116da565b611701816109e8565b9561170b87610a8d565b5061171590611277565b61171f85896109f6565b611729908561137f565b51806101408301519061173b916119c4565b8151602080840151604080860151905160609290921b6bffffffffffffffffffffffff191692820192835260348083019190915281526001600160a01b0390921693916117896054826107fd565b51902060608201519091906001600160a01b031660808201516001600160801b031660a08301516001600160801b031660c08401519160e08501516117d4906001600160401b031690565b6101008601519094906001600160a01b0316956101200151966117f5610830565b6001600160a01b03909a168a5260208a01526001600160a01b031660408901526001600160801b031660608801526001600160801b0316608087015260a08601526001600160401b031660c08501526001600160a01b031660e0840152610100830152610120820152604051809160208201936118729185611393565b03601f198101825261188490826107fd565b5190209561189190610a8d565b61189a916114bc565b5f19016116c1565b630db2128560e11b5f52600452602483905260445ffd5b92505f6115d7565b631391e11b60e21b5f5260045ffd5b50604051630b83774760e31b81526020816004817f0000000000000000000000001c000000000000000000000000000000000000036001600160a01b03165afa908115610411575f91611930575b506001600160a01b03163314156115a8565b611949915060203d60201161040a576103fc81836107fd565b5f61191e565b805180156119c0576021036119a257805115610aa95760208101516001600160f81b031916600160f91b81141590816119b1575b506119a257611998602161199c920151611a46565b1590565b6119a257565b6361d0136b60e11b5f5260045ffd5b600360f81b141590505f611983565b5050565b516119ed575f905b518181036119d8575050565b63521a2d4d60e11b5f5260045260245260445ffd5b6071906119cc565b3d15611a1f573d90611a06826108ee565b91611a1460405193846107fd565b82523d5f602084013e565b606090565b602081519101519060208110611a38575090565b5f199060200360031b1b1690565b80158015611b04575b611af3575f8091604051611ac981611abb602082019460076401000003d019916401000003d019906401000003d019818009090860208087528087018190526040870152606086015263800001e9600160ff1b0360808601526401000003d01960a086015260c0850190565b03601f1981018352826107fd565b519060055afa611ad76119f5565b90158015611af8575b611af357611aef600191611a24565b1490565b505f90565b50602081511415611ae0565b506401000003d019811015611a4f56fea2646970667358221220c507a58923eeb01609f13c1e26604cbb46eaf7befa4f49f7c8ce5aca93e940d264736f6c634300081e0033" }, "0x1c00000000000000000000000000000000000003": { "nonce": "0x1", "balance": "0x0", - "code": "0x6080806040526004361015610012575f80fd5b5f3560e01c9081631beb1ab814610561575080631fbb25ad1461051d5780633488ce0d146102dd5780635c1bba381461023b5780636d46e98714610193578063a21de6d91461014f5763e202d99514610069575f80fd5b34610138575f366003190112610138576040516381e3da6b60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015260016024830152602090829060449082907f0000000000000000000000001c00000000000000000000000000000000000000165afa8015610144575f9061010d575b6040516001600160a01b039091168152602090f35b506020813d60201161013c575b816101276020938361067c565b8101031261013857602090516100f8565b5f80fd5b3d915061011a565b6040513d5f823e3d90fd5b34610138575f366003190112610138576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610138576020366003190112610138576004356001600160a01b0381169081900361013857604051630b83774760e31b8152602081600481305afa908115610144575f916101f6575b506040516001600160a01b039091169091148152602090f35b90506020813d602011610233575b816102116020938361067c565b810103126101385751906001600160a01b0382168203610138579060206101dd565b3d9150610204565b34610138575f366003190112610138576040516381e3da6b60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f6024830152602090829060449082907f0000000000000000000000001c00000000000000000000000000000000000000165afa8015610144575f9061010d576040516001600160a01b039091168152602090f35b34610138575f366003190112610138576040516381e3da6b60e01b81527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b038181166004840152600660248401527f0000000000000000000000001c00000000000000000000000000000000000000169190602082604481865afa918215610144575f926104e9575b5081156104da576040516020810190600682526020815261038f60408261067c565b519020915f1981019081116104c6578060011b90808204600214901517156104c65782018092116104c65760018201908183116104c6576040516381e3da6b60e01b81526001600160a01b03821660048201526024810193909352602083604481875afa928315610144575f9361048e575b506040516381e3da6b60e01b81526001600160a01b03909116600482015260248101919091529160209083908180604481015b03915afa918215610144575f92610459575b5060ff6040928351928352166020820152f35b91506020823d602011610486575b816104746020938361067c565b810103126101385790519060ff610446565b3d9150610467565b919092506020823d6020116104be575b816104ab6020938361067c565b8101031261013857905191610434610401565b3d915061049e565b634e487b7160e01b5f52601160045260245ffd5b630c322fb560e31b5f5260045ffd5b9091506020813d602011610515575b816105056020938361067c565b810103126101385751908361036d565b3d91506104f8565b34610138575f366003190112610138576040517f0000000000000000000000001c000000000000000000000000000000000000006001600160a01b03168152602090f35b34610138576020366003190112610138576004356001600160a01b0381169190829003610138576105fe9181602080930191825260076040820152604081526105ab60608261067c565b5190206040516381e3da6b60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152602481019190915291829081906044820190565b03817f0000000000000000000000001c000000000000000000000000000000000000006001600160a01b03165afa8015610144575f90610649575b60209060ff604051911615158152f35b506020813d602011610674575b816106636020938361067c565b810103126101385760209051610639565b3d9150610656565b90601f8019910116810190811067ffffffffffffffff82111761069e57604052565b634e487b7160e01b5f52604160045260245ffdfea2646970667358221220615455022182404b5eef598e1c4e66b9fba2ee08aa579832c0c247d1afef17a164736f6c63430008210033" + "code": "0x6080806040526004361015610012575f80fd5b5f3560e01c9081631beb1ab814610561575080631fbb25ad1461051d5780633488ce0d146102dd5780635c1bba381461023b5780636d46e98714610193578063a21de6d91461014f5763e202d99514610069575f80fd5b34610138575f366003190112610138576040516381e3da6b60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015260016024830152602090829060449082907f0000000000000000000000001c00000000000000000000000000000000000000165afa8015610144575f9061010d575b6040516001600160a01b039091168152602090f35b506020813d60201161013c575b816101276020938361067c565b8101031261013857602090516100f8565b5f80fd5b3d915061011a565b6040513d5f823e3d90fd5b34610138575f366003190112610138576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610138576020366003190112610138576004356001600160a01b0381169081900361013857604051630b83774760e31b8152602081600481305afa908115610144575f916101f6575b506040516001600160a01b039091169091148152602090f35b90506020813d602011610233575b816102116020938361067c565b810103126101385751906001600160a01b0382168203610138579060206101dd565b3d9150610204565b34610138575f366003190112610138576040516381e3da6b60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f6024830152602090829060449082907f0000000000000000000000001c00000000000000000000000000000000000000165afa8015610144575f9061010d576040516001600160a01b039091168152602090f35b34610138575f366003190112610138576040516381e3da6b60e01b81527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b038181166004840152600660248401527f0000000000000000000000001c00000000000000000000000000000000000000169190602082604481865afa918215610144575f926104e9575b5081156104da576040516020810190600682526020815261038f60408261067c565b519020915f1981019081116104c6578060011b90808204600214901517156104c65782018092116104c65760018201908183116104c6576040516381e3da6b60e01b81526001600160a01b03821660048201526024810193909352602083604481875afa928315610144575f9361048e575b506040516381e3da6b60e01b81526001600160a01b03909116600482015260248101919091529160209083908180604481015b03915afa918215610144575f92610459575b5060ff6040928351928352166020820152f35b91506020823d602011610486575b816104746020938361067c565b810103126101385790519060ff610446565b3d9150610467565b919092506020823d6020116104be575b816104ab6020938361067c565b8101031261013857905191610434610401565b3d915061049e565b634e487b7160e01b5f52601160045260245ffd5b630c322fb560e31b5f5260045ffd5b9091506020813d602011610515575b816105056020938361067c565b810103126101385751908361036d565b3d91506104f8565b34610138575f366003190112610138576040517f0000000000000000000000001c000000000000000000000000000000000000006001600160a01b03168152602090f35b34610138576020366003190112610138576004356001600160a01b0381169190829003610138576105fe9181602080930191825260076040820152604081526105ab60608261067c565b5190206040516381e3da6b60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152602481019190915291829081906044820190565b03817f0000000000000000000000001c000000000000000000000000000000000000006001600160a01b03165afa8015610144575f90610649575b60209060ff604051911615158152f35b506020813d602011610674575b816106636020938361067c565b810103126101385760209051610639565b3d9150610656565b90601f8019910116810190811067ffffffffffffffff82111761069e57604052565b634e487b7160e01b5f52604160045260245ffdfea26469706673582212202123abc3d91c41a1be59b6f06bfc92259b93aa367f581f04eda761e4ed25c63c64736f6c634300081e0033" }, "0x1c00000000000000000000000000000000000004": { "nonce": "0x1", @@ -96,46 +96,6 @@ "0xc39d774f18115b85b81494d65e588b565d73abc969333d1da7b0a0eb0729accd": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } }, - "0x20c0000000000000000000000000000000000001": { - "nonce": "0x0", - "balance": "0x0", - "code": "0xef", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x416c706861555344000000000000000000000000000000000000000000000010", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x416c706861555344000000000000000000000000000000000000000000000010", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x5553440000000000000000000000000000000000000000000000000000000006", - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x00000000000000000000000020c0000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000007": "0x00000000000000000000000120c0000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000008": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000000000d": "0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff", - "0x1a08d1eefb6dea6eba7c6c1f53fa17f31dc24b9efe98e97550f0dad434642618": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x353fe882519f79b8caf8d301c26c19d663ae2e691ca2e75dc341b346d5d22c63": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x983ee3ed0ac6ffe1e6626c807d5dad57db7645721c041f19b39c3f728acefdd7": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x9a3d8dc9bf2bb7465d975ea80af65f820bc69e3b43668ac11765d4e28cf9333a": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xbd1422d956203483f6a77a55f068041e264cef0ec8c355db258a1fb8f4169a51": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xc39d774f18115b85b81494d65e588b565d73abc969333d1da7b0a0eb0729accd": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - } - }, - "0x20c0000000000000000000000000000000000002": { - "nonce": "0x0", - "balance": "0x0", - "code": "0xef", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x426574615553440000000000000000000000000000000000000000000000000e", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x426574615553440000000000000000000000000000000000000000000000000e", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x5553440000000000000000000000000000000000000000000000000000000006", - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x00000000000000000000000020c0000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000007": "0x00000000000000000000000120c0000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000008": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000000000d": "0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff", - "0x1a08d1eefb6dea6eba7c6c1f53fa17f31dc24b9efe98e97550f0dad434642618": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x353fe882519f79b8caf8d301c26c19d663ae2e691ca2e75dc341b346d5d22c63": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x983ee3ed0ac6ffe1e6626c807d5dad57db7645721c041f19b39c3f728acefdd7": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x9a3d8dc9bf2bb7465d975ea80af65f820bc69e3b43668ac11765d4e28cf9333a": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xbd1422d956203483f6a77a55f068041e264cef0ec8c355db258a1fb8f4169a51": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xc39d774f18115b85b81494d65e588b565d73abc969333d1da7b0a0eb0729accd": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - } - }, "0x20fc000000000000000000000000000000000000": { "nonce": "0x0", "balance": "0x0", @@ -191,4 +151,4 @@ } }, "baseFeePerGas": "0x2540be400" -} +} \ No newline at end of file diff --git a/docs/pages/protocol/privacy/crypto-review.md b/docs/pages/protocol/privacy/crypto-review.md new file mode 100644 index 000000000..91d66b1f6 --- /dev/null +++ b/docs/pages/protocol/privacy/crypto-review.md @@ -0,0 +1,385 @@ +# Cryptography review checklist + +This document lists the cryptographic constructions in the zone privacy specification that require expert review. The focus is on spec-level correctness — whether the protocols are sound, the parameters are safe, and the trust assumptions are clearly stated. + +For each construction, we include the security model and an extract of the spec sections a reviewer should read. + +--- + +## 1. Encrypted deposits (ECIES + Chaum-Pedersen) + +### Security model + +**Functionality**: Users can deposit tokens into a zone while hiding the recipient address and memo. The construction provides three guarantees: + +1. **Correct encryption → recipient is credited.** If the user correctly encrypts `(to, memo)` to the sequencer's published encryption key, the zone credits `to` with the deposited amount. If the mint to `to` fails (e.g. the recipient is blocked by TIP-403 token policy), the zone falls back to crediting the depositor instead. The sequencer cannot selectively reject a correctly encrypted deposit without halting the processing of *all* deposits — the deposit queue is an ordered hash chain, so skipping one deposit means all subsequent deposits stall. + +2. **Incorrect encryption → refund on L1.** If the ciphertext is malformed, encrypted to the wrong key, or otherwise fails decryption, the deposit amount is minted to the `sender` address on the zone (the same account that deposited on L1). The L1 funds remain escrowed in the portal. Chain progress is never blocked by invalid encrypted deposits. + +3. **Sequencer cannot lie about decryption.** The sequencer provides the ECDH shared secret and a Chaum-Pedersen DLEQ proof that it was correctly derived. The AES-GCM authentication tag then verifies the decrypted plaintext. Together, these prevent the sequencer from claiming a deposit decrypts to a different `(to, memo)` — the GCM tag would fail. The only attack is refusing to process at all, which triggers the refund path. + +**Trust assumptions**: +- The sequencer's encryption key is registered on-chain with a proof-of-possession (ECDSA signature). Users trust this key is honestly generated. +- The `token`, `sender`, and `amount` fields are always public (needed for on-chain escrow accounting). Only `to` and `memo` are encrypted. +- A compromised sequencer private key exposes all past and future encrypted deposit recipients until key rotation. Old keys remain valid for a grace period (86,400 blocks ≈ 1 day). Deposits using a compromised old key during the grace period are retroactively exposed. + +**Cryptographic components** (reviewed together because they form a single verification pipeline): +- **ECIES**: secp256k1 ECDH + HKDF-SHA256 + AES-256-GCM — encrypts `(to, memo)`. +- **Chaum-Pedersen DLEQ proof**: non-interactive sigma protocol (Fiat-Shamir) — proves the sequencer used the correct private key for ECDH, preventing griefing with deposits encrypted to the wrong key. +- **Secp256k1 point validation**: Euler's criterion via MODEXP precompile — validates ephemeral public keys on the portal to prevent invalid-point griefing. + +### Spec extract + +**Encryption scheme** (ECIES with secp256k1): + +1. Sequencer publishes a secp256k1 encryption public key via `setSequencerEncryptionKey(x, yParity, popV, popR, popS)` with a proof-of-possession (ECDSA signature over `keccak256(abi.encode(portalAddress, x, yParity))` by the corresponding private key). +2. User generates an ephemeral keypair and derives a shared secret via ECDH. +3. AES-256 key derived via HKDF-SHA256 with salt `"ecies-aes-key"` and info `abi.encodePacked(tempoPortal, keyIndex, ephemeralPubkeyX)`. +4. Plaintext `(to || memo || padding)` = 64 bytes (20 addr + 32 memo + 12 zero padding) encrypted with AES-256-GCM (empty AAD, user-chosen 12-byte nonce). +5. User calls `depositEncrypted(token, amount, keyIndex, encryptedPayload)` on the portal. + +**On-chain types** (`IZone.sol`): + +```solidity +struct EncryptedDepositPayload { + bytes32 ephemeralPubkeyX; // Ephemeral public key X coordinate (for ECDH) + uint8 ephemeralPubkeyYParity; // Y coordinate parity (0x02 or 0x03) + bytes ciphertext; // AES-256-GCM encrypted (to || memo || padding) + bytes12 nonce; // GCM nonce + bytes16 tag; // GCM authentication tag +} + +struct EncryptedDeposit { + address token; // TIP-20 token (public, for escrow accounting) + address sender; // Depositor (public, for refunds) + uint128 amount; // Amount (public, for accounting) + uint256 keyIndex; // Index of encryption key used (specified by depositor) + EncryptedDepositPayload encrypted; +} + +struct DecryptionData { + bytes32 sharedSecret; // ECDH shared secret (x-coordinate of privSeq * ephemeralPub) + uint8 sharedSecretYParity; // Y coordinate parity of the shared secret point (0x02 or 0x03) + ChaumPedersenProof cpProof; // Proof of correct shared secret derivation +} + +struct ChaumPedersenProof { + bytes32 s; // Response: s = r + c * privSeq (mod n) + bytes32 c; // Challenge: c = hash(G, ephemeralPub, pubSeq, sharedSecretPoint, R1, R2) +} +``` + +**On-chain verification pipeline** (`ZoneInbox.sol`, `advanceTempo`): + +```solidity +// Step 1: Verify Chaum-Pedersen DLEQ proof — proves shared secret was derived correctly +(bytes32 seqPubX, uint8 seqPubYParity) = _readEncryptionKey(ed.keyIndex); +bool proofValid = IChaumPedersenVerify(CHAUM_PEDERSEN_VERIFY).verifyProof( + ed.encrypted.ephemeralPubkeyX, + ed.encrypted.ephemeralPubkeyYParity, + dec.sharedSecret, + dec.sharedSecretYParity, + seqPubX, + seqPubYParity, + dec.cpProof +); +if (!proofValid) revert InvalidSharedSecretProof(); + +// Step 2: Derive AES key from shared secret using HKDF-SHA256 +bytes32 aesKey = _hkdfSha256( + dec.sharedSecret, + "ecies-aes-key", + abi.encodePacked(tempoPortal, ed.keyIndex, ed.encrypted.ephemeralPubkeyX) +); + +// Step 3: Decrypt using AES-256-GCM precompile +(bytes memory decryptedPlaintext, bool valid) = IAesGcmDecrypt(AES_GCM_DECRYPT).decrypt( + aesKey, ed.encrypted.nonce, ed.encrypted.ciphertext, "", ed.encrypted.tag +); + +// Step 4: Decode the decrypted (to, memo) from the plaintext +address decryptedTo; +bytes32 decryptedMemo; +if (valid && decryptedPlaintext.length == ENCRYPTED_PAYLOAD_PLAINTEXT_SIZE) { + (decryptedTo, decryptedMemo) = + EncryptedDepositLib.decodePlaintext(decryptedPlaintext); +} else { + valid = false; +} + +// Step 5: Mint to decrypted recipient on success, or refund to sender on failure. +// If the mint to decryptedTo fails (e.g. TIP-403 policy rejects the recipient), +// fall back to crediting the depositor. +if (!valid) { + IZoneToken(ed.token).mint(ed.sender, ed.amount); +} else { + try IZoneToken(ed.token).mint(decryptedTo, ed.amount) {} catch { + IZoneToken(ed.token).mint(ed.sender, ed.amount); + } +} +``` + +The sequencer's public key (`seqPubX`, `seqPubYParity`) is looked up on-chain via `_readEncryptionKey(ed.keyIndex)`, which reads from the portal's storage through `TempoState.readTempoStorageSlot`. It is not supplied by the sequencer in `DecryptionData`, preventing substitution attacks. + +**Chaum-Pedersen DLEQ protocol**: + +Proves knowledge of `privSeq` such that `pubSeq = privSeq * G` AND `sharedSecretPoint = privSeq * ephemeralPub`: + +1. **Prover (sequencer) computes off-chain:** + - Pick random `r` + - `R1 = r * G` + - `R2 = r * ephemeralPub` + - `c = hash(G, ephemeralPub, pubSeq, sharedSecretPoint, R1, R2)` (Fiat-Shamir challenge) + - `s = r + c * privSeq (mod n)` + - Proof is `(s, c)` + +2. **Verifier (on-chain precompile at `0x1C00...0100`) checks:** + - Reconstruct: `R1 = s*G - c*pubSeq` + - Reconstruct: `R2 = s*ephemeralPub - c*sharedSecretPoint` + - Recompute: `c' = hash(G, ephemeralPub, pubSeq, sharedSecretPoint, R1, R2)` + - Verify: `c == c'` + +**Precompile interface** (`IZone.sol`): + +```solidity +interface IChaumPedersenVerify { + function verifyProof( + bytes32 ephemeralPubX, + uint8 ephemeralPubYParity, + bytes32 sharedSecret, + uint8 sharedSecretYParity, + bytes32 sequencerPubX, + uint8 sequencerPubYParity, + ChaumPedersenProof calldata proof + ) external view returns (bool valid); +} +``` + +**HKDF-SHA256 implementation** (`ZoneInbox.sol`): + +```solidity +function _hkdfSha256(bytes32 ikm, bytes memory salt, bytes memory info) + internal view returns (bytes32 okm) +{ + // HKDF-Extract: PRK = HMAC-SHA256(salt, IKM) + bytes32 prk = _hmacSha256(salt, abi.encodePacked(ikm)); + // HKDF-Expand: OKM = HMAC-SHA256(PRK, info || 0x01) + bytes memory expandInput = bytes.concat(info, hex"01"); + okm = _hmacSha256(abi.encodePacked(prk), expandInput); +} +``` + +**Ephemeral pubkey validation** (`ZonePortal.sol`): + +The portal validates the ephemeral public key X coordinate is on secp256k1 using Euler's criterion via the MODEXP precompile: `(x³ + 7)^((p-1)/2) ≡ 1 (mod p)`. This prevents griefing with invalid points that would make ECDH and Chaum-Pedersen proofs impossible. + +**Key rotation** (`ZonePortal.sol`): + +Old encryption keys expire after `ENCRYPTION_KEY_GRACE_PERIOD = 86,400` blocks (~1 day at 1s block time). The current key never expires. Users specify `keyIndex` at signing time to avoid race conditions during rotation. Deposits using expired keys are rejected with `EncryptionKeyExpired`. + +--- + +## 2. Authenticated withdrawals — sender tag + +### Security model + +**Functionality**: Hide the identity of the withdrawal sender from public observers on Tempo Mainnet, while allowing the sender to selectively disclose their identity to chosen parties. + +**Trust assumptions**: +- The sequencer computes `senderTag` and includes it in the `Withdrawal` struct. The struct is hashed into the withdrawal queue chain committed in the batch proof. **The sequencer is trusted to compute the tag correctly.** A malicious sequencer could forge tags attributing withdrawals to wrong senders, or produce unverifiable tags. The batch proof would still be valid since the prover does not verify the tag's preimage. +- This is a modest extension of the existing trust model: the sequencer is already trusted for liveness, transaction ordering, and withdrawal processing. +- The blinding factor `txHash` is known to the sequencer and anyone with zone data access. The threat model relies on zone transaction data not being published on L1. +- To upgrade to trustless sender authentication, `senderTag` computation can be moved into the ZK circuit. The encryption would remain sequencer-mediated. + +**Threat surface**: +- An observer who learns `txHash` (e.g., from a compromised sequencer) can deanonymize the sender. +- The commitment is hiding under the assumption that `txHash` is uniformly random and secret. Since `txHash = keccak256(transaction)`, it is uniformly distributed, but secrecy depends entirely on zone data privacy. + +### Spec extract + +**Sender tag computation** (overview.md §"Authenticated withdrawals", `ZoneOutbox.sol` line 362): + +``` +senderTag = keccak256(abi.encodePacked(sender, txHash)) +``` + +where `sender` is the address that called `requestWithdrawal` on the zone and `txHash` is the hash of that zone transaction. The `txHash` acts as a 32-byte blinding factor — it is private to the zone and known only to the sender and the sequencer. + +**On-chain construction** (`ZoneOutbox.sol`, `finalizeWithdrawalBatch`): + +```solidity +Withdrawal memory w = Withdrawal({ + token: pendingWithdrawal.token, + senderTag: keccak256( + abi.encodePacked(pendingWithdrawal.sender, pendingWithdrawal.txHash) + ), + to: pendingWithdrawal.to, + amount: pendingWithdrawal.amount, + fee: pendingWithdrawal.fee, + memo: pendingWithdrawal.memo, + gasLimit: pendingWithdrawal.gasLimit, + fallbackRecipient: pendingWithdrawal.fallbackRecipient, + callbackData: pendingWithdrawal.callbackData, + encryptedSender: encryptedSender +}); +``` + +The `txHash` is obtained from the `ZoneTxContext` precompile (`0x1c00...0005`) at withdrawal request time: + +```solidity +bytes32 txHash = IZoneTxContext(ZONE_TX_CONTEXT).currentTxHash(); +``` + +**Selective disclosure** (overview.md §"Selective disclosure"): + +- **Manual reveal**: sender reveals `txHash` off-chain. Verifier checks `keccak256(abi.encodePacked(sender, txHash)) == senderTag`. +- **Encrypted reveal**: if `revealTo` was specified, the holder of the `revealTo` private key decrypts `encryptedSender` to obtain `(sender, txHash)` and verifies against `senderTag`. + +--- + +## 3. Authenticated withdrawals — encrypted sender reveal + +### Security model + +**Functionality**: Enable automated sender disclosure for cross-zone transfers. The sequencer encrypts `(sender, txHash)` to a `revealTo` public key specified by the sender, so the holder of the corresponding private key can learn the sender's identity without off-chain coordination. + +**Trust assumptions**: +- The sequencer is trusted to encrypt correctly. A malicious sequencer could encrypt garbage or use a different key. This is acceptable since the sequencer already knows `sender` and `txHash` and could withhold them. +- The sender cannot perform the encryption themselves because `txHash` depends on the transaction contents (circular dependency). The sequencer encrypts post-hoc. +- Cross-zone scenario: if Zone B's sequencer holds the `revealTo` private key and is compromised, all sender identities for transfers to Zone B are exposed. + +**Threat surface**: +- The `encryptedSender` ciphertext is in L1 calldata (public). The ciphertext is fixed-length (113 bytes) to avoid length-based information leakage. +- The symmetric cipher and MAC used for the inner encryption are not fully specified in the overview document. The `ZoneOutbox.sol` defines the format but the KDF and cipher choice should be made explicit. + +### Spec extract + +**Withdrawal request** (`ZoneOutbox.sol`): + +The sender specifies an optional `revealTo` compressed secp256k1 public key (33 bytes) when calling `requestWithdrawal`. The outbox validates the key: + +```solidity +function _validateRevealTo(bytes memory revealTo) internal view { + if (revealTo.length == 0) return; + if (revealTo.length != REVEAL_TO_KEY_LENGTH) revert InvalidRevealTo(); // 33 bytes + bytes1 prefix = revealTo[0]; + if (prefix != 0x02 && prefix != 0x03) revert InvalidRevealTo(); + bytes32 x; + assembly { x := mload(add(revealTo, 33)) } + if (!_isValidSecp256k1X(x)) revert InvalidRevealTo(); +} +``` + +**Encrypted sender format** (`ZoneOutbox.sol`, overview.md §"Encrypted sender format"): + +When `revealTo` is specified, `encryptedSender` is exactly 113 bytes: + +``` +ephemeralPubKey (33 bytes) || nonce (12 bytes) || ciphertext (52 bytes) || tag (16 bytes) +``` + +The sequencer generates an ephemeral key pair `(r, R = r*G)`, derives a shared secret `S = r * revealTo` (ECDH), and encrypts `abi.encodePacked(sender, txHash)` (52 bytes). + +**Length validation** (`ZoneOutbox.sol`): + +```solidity +uint256 public constant AUTHENTICATED_WITHDRAWAL_CIPHERTEXT_LENGTH = 113; + +function _validateEncryptedSender(bytes memory revealTo, bytes memory encryptedSender) internal pure { + uint256 expectedLength = revealTo.length == 0 ? 0 : AUTHENTICATED_WITHDRAWAL_CIPHERTEXT_LENGTH; + if (encryptedSender.length != expectedLength) { + revert InvalidEncryptedSenderLength(encryptedSender.length, expectedLength); + } +} +``` + +**Zone-to-zone flow** (overview.md §"Zone-to-zone transfers"): + +1. Sender on Zone A calls `requestWithdrawal` with `revealTo = pubKeySeqB`. +2. Zone A's sequencer computes `senderTag` and `encryptedSender`. +3. Withdrawal is proven and submitted to L1. `processWithdrawal` transfers tokens to Zone B's portal. +4. Zone B's sequencer reads `encryptedSender`, decrypts with its private key to learn `(sender, txHash)`. +5. Zone B verifies `keccak256(sender || txHash) == senderTag`. + +--- + +## 4. RPC authorization tokens + +### Security model + +**Functionality**: Authenticate every RPC request to a zone, scoping all responses to the caller's account. Tokens are read-only credentials — no RPC method authenticated solely by a token may modify state (withdrawals require a full transaction signature). + +**Trust assumptions**: +- The token hash uses raw `keccak256` (not EIP-191/712) because P256 and WebAuthn signers cannot produce EIP-191 prefixed signatures. The `"TempoZoneRPC"` magic prefix must provide sufficient domain separation. +- Tokens are replayable within their validity window by design. The spec states this is acceptable because they are read-only credentials. Stolen tokens cannot move funds. +- Unscoped tokens (`zoneId = 0`) are valid for any zone on the network. Since tokens are read-only, this limits exposure to read access across zones. +- Keychain Access Keys use the zone's own `AccountKeychain` instance (not mirrored from Tempo L1). Revocation must be honored within 1 second of the revoking block being imported. + +**Threat surface**: +- A stolen token grants read access to the victim's account data (balances, transaction history, events) for up to 30 days. +- If the magic prefix collides with another signing context, a valid RPC token could be replayed as a different signed message, or vice versa. +- WebAuthn verification skips RP ID hash and origin validation. The challenge binding to `authorizationTokenHash` must be sufficient. + +### Spec extract + +**Token hash** (`rpc.md` §"Authorization tokens"): + +```solidity +bytes32 authorizationTokenHash = keccak256(abi.encodePacked( + bytes32(0x54656d706f5a6f6e65525043), // "TempoZoneRPC" magic prefix + uint8(version), // spec version (currently 0) + uint32(zoneId), // zone this key is valid for (0 = unscoped) + uint64(chainId), // zone chain ID (replay protection) + uint64(issuedAt), // unix timestamp (seconds) of issuance + uint64(expiresAt) // unix timestamp (seconds) of expiry +)); +``` + +**Signature types** (`rpc.md` §"Signature types"): + +| Type | Detection | Address derivation | +|------|-----------|-------------------| +| **secp256k1** | Exactly 65 bytes, no type prefix | `ecrecover` → address | +| **P256** | First byte `0x01`, 130 bytes total | Address from embedded pubkey | +| **WebAuthn** | First byte `0x02`, variable length (max 2KB) | Same as P256 | +| **Keychain** | First byte `0x03` (V1) or `0x04` (V2), variable length | Authenticated account is `user_address`, not signing key | + +**Transport wire format** (`rpc.md` §"Transport"): + +``` + +``` + +The token fields are always exactly 29 bytes. The server reads the last 29 bytes as token fields, everything before is the signature. Parsing from the end avoids ambiguity with variable-length signatures. + +**Validation rules** (`rpc.md` §"Validation"): + +- `zoneId` must match the zone's ID or be `0` (unscoped). +- `chainId` must match `eth_chainId`. +- `expiresAt - issuedAt > 2,592,000` (30 days max) → reject. +- `expiresAt <= now` → reject. +- `issuedAt > now + 60` (60-second clock skew tolerance) → reject. +- Keychain: signing key must be active, non-revoked, non-expired in `AccountKeychain`. + +**Keychain V2 signing hash** (`rpc.md` §"Keychain Access Keys"): + +V2 binds `user_address` into the signing hash: inner signature is over `keccak256(0x04 || authorizationTokenHash || user_address)`. V1 signs the raw `authorizationTokenHash` directly. + +**WebAuthn verification** (`rpc.md` §"WebAuthn"): + +Verified: authenticatorData length, UP/UV flags, AT flag NOT set, ED flag NOT set, `clientDataJSON.type == "webauthn.get"`, challenge matches `authorizationTokenHash` (Base64URL), P256 signature valid. + +Skipped: RP ID hash (no single relying party), `clientDataJSON.origin` (no canonical origin), signature counter (anti-cloning left to app layer). + +--- + +## Files to review + +| Area | Spec (documentation) | Solidity spec | +|------|---------------------|---------------| +| Encrypted deposits (ECIES + Chaum-Pedersen) | [overview.md](overview.md) §"Encrypted deposits", [prover-design.md](prover-design.md) | [IZone.sol](../../../specs/src/zone/IZone.sol), [ZoneInbox.sol](../../../specs/src/zone/ZoneInbox.sol), [EncryptedDeposit.sol](../../../specs/src/zone/EncryptedDeposit.sol) | +| Sender tag | [overview.md](overview.md) §"Authenticated withdrawals" | [IZone.sol](../../../specs/src/zone/IZone.sol) (`Withdrawal.senderTag`), [ZoneOutbox.sol](../../../specs/src/zone/ZoneOutbox.sol) | +| Encrypted sender | [overview.md](overview.md) §"Reveal key", §"Encrypted sender format" | [IZone.sol](../../../specs/src/zone/IZone.sol), [ZoneOutbox.sol](../../../specs/src/zone/ZoneOutbox.sol) | +| RPC auth tokens | [rpc.md](rpc.md) §"Authorization tokens" | — | +| Point validation | — | [ZonePortal.sol](../../../specs/src/zone/ZonePortal.sol) (`_isValidSecp256k1X`), [ZoneOutbox.sol](../../../specs/src/zone/ZoneOutbox.sol) (`_isValidSecp256k1X`) | +| Key rotation | [overview.md](overview.md) §"Encrypted deposits" | [ZonePortal.sol](../../../specs/src/zone/ZonePortal.sol) (`setSequencerEncryptionKey`, `isEncryptionKeyValid`) | diff --git a/docs/specs/src/zone/IZone.sol b/docs/specs/src/zone/IZone.sol index 0af0939cc..908d7479c 100644 --- a/docs/specs/src/zone/IZone.sol +++ b/docs/specs/src/zone/IZone.sol @@ -141,11 +141,11 @@ struct ChaumPedersenProof { /// without exposing the sequencer's private key. /// The sequencer's public key is looked up from the deposit's keyIndex on-chain, /// so it does not need to be included here. +/// The decrypted (to, memo) are derived on-chain from the AES-GCM decryption and +/// do not need to be supplied by the sequencer. struct DecryptionData { bytes32 sharedSecret; // ECDH shared secret (x-coordinate of privSeq * ephemeralPub) uint8 sharedSecretYParity; // Y coordinate parity of the shared secret point (0x02 or 0x03) - address to; // Decrypted recipient - bytes32 memo; // Decrypted memo ChaumPedersenProof cpProof; // Proof of correct shared secret derivation } diff --git a/docs/specs/src/zone/ZoneInbox.sol b/docs/specs/src/zone/ZoneInbox.sol index 46a7fd736..0053cc855 100644 --- a/docs/specs/src/zone/ZoneInbox.sol +++ b/docs/specs/src/zone/ZoneInbox.sol @@ -260,13 +260,14 @@ contract ZoneInbox is IZoneInbox { ed.encrypted.tag ); - // Step 4: Verify decrypted plaintext matches claimed (to, memo) + // Step 4: Decode the decrypted (to, memo) from the plaintext // Plaintext is packed as [address(20 bytes)][memo(32 bytes)][padding(12 bytes)] // Must be exactly ENCRYPTED_PAYLOAD_PLAINTEXT_SIZE (64) bytes + address decryptedTo; + bytes32 decryptedMemo; if (valid && decryptedPlaintext.length == ENCRYPTED_PAYLOAD_PLAINTEXT_SIZE) { - (address decryptedTo, bytes32 decryptedMemo) = + (decryptedTo, decryptedMemo) = EncryptedDepositLib.decodePlaintext(decryptedPlaintext); - valid = (decryptedTo == dec.to && decryptedMemo == dec.memo); } else { valid = false; } @@ -280,11 +281,17 @@ contract ZoneInbox is IZoneInbox { IZoneToken(ed.token).mint(ed.sender, ed.amount); emit EncryptedDepositFailed(currentHash, ed.sender, ed.token, ed.amount); } else { - // Decryption succeeded - mint the correct zone-side TIP-20 to the decrypted recipient - IZoneToken(ed.token).mint(dec.to, ed.amount); - emit EncryptedDepositProcessed( - currentHash, ed.sender, dec.to, ed.token, ed.amount, dec.memo - ); + // Decryption succeeded — try minting to the decrypted recipient. + // If the mint fails (e.g. recipient is blacklisted by TIP-403 + // policy), fall back to crediting the depositor instead. + try IZoneToken(ed.token).mint(decryptedTo, ed.amount) { + emit EncryptedDepositProcessed( + currentHash, ed.sender, decryptedTo, ed.token, ed.amount, decryptedMemo + ); + } catch { + IZoneToken(ed.token).mint(ed.sender, ed.amount); + emit EncryptedDepositFailed(currentHash, ed.sender, ed.token, ed.amount); + } } } } diff --git a/docs/specs/test/zone/ZoneBridge.t.sol b/docs/specs/test/zone/ZoneBridge.t.sol index 37ea7f2cf..a6d1aa15b 100644 --- a/docs/specs/test/zone/ZoneBridge.t.sol +++ b/docs/specs/test/zone/ZoneBridge.t.sol @@ -967,8 +967,6 @@ contract ZoneBridgeTest is BaseTest { decs[i] = DecryptionData({ sharedSecret: bytes32(uint256(0xDEAD)), sharedSecretYParity: 0x02, - to: decryptedTo, - memo: decryptedMemo, cpProof: ChaumPedersenProof({ s: bytes32(uint256(1)), c: bytes32(uint256(2)) }) }); } @@ -1090,7 +1088,7 @@ contract ZoneBridgeTest is BaseTest { _sequencerObserveEncryptedDeposit(alice, netAmount, 0, payload); _setupEncryptionKeyMockOnZone(0, encKeyX, encKeyYParity); - // Even with shouldSucceed=false, we need a to/memo for DecryptionData (values don't matter) + // Even with shouldSucceed=false, we still call the relay helper bytes32 newProcessedHash = _sequencerRelayEncryptedDepositsToL2(address(0xBEEF), bytes32("wrong"), false); @@ -1196,8 +1194,6 @@ contract ZoneBridgeTest is BaseTest { decs[0] = DecryptionData({ sharedSecret: bytes32(uint256(0xDEAD)), sharedSecretYParity: 0x02, - to: decryptedTo, - memo: decryptedMemo, cpProof: ChaumPedersenProof({ s: bytes32(uint256(1)), c: bytes32(uint256(2)) }) }); @@ -1309,15 +1305,11 @@ contract ZoneBridgeTest is BaseTest { decs[0] = DecryptionData({ sharedSecret: bytes32(uint256(0xDEAD)), sharedSecretYParity: 0x02, - to: aliceRecipient, - memo: aliceMemo, cpProof: ChaumPedersenProof({ s: bytes32(uint256(1)), c: bytes32(uint256(2)) }) }); decs[1] = DecryptionData({ sharedSecret: bytes32(uint256(0xBEEF)), sharedSecretYParity: 0x02, - to: bobRecipient, - memo: bobMemo, cpProof: ChaumPedersenProof({ s: bytes32(uint256(3)), c: bytes32(uint256(4)) }) }); @@ -1329,30 +1321,11 @@ contract ZoneBridgeTest is BaseTest { address(l1Portal), PORTAL_CURRENT_DEPOSIT_QUEUE_HASH_SLOT, hash2 ); - // Mock precompiles — we use broad mocks since vm.mockCall matches any input - // For the success path, we need AES-GCM to return the correct plaintext. - // Since vm.mockCall with just the selector matches ALL calls, we mock for the LAST - // decryption (bobRecipient). For aliceRecipient we set up mock before advanceTempo, - // but vm.mockCall replaces: we need a workaround. - // - // Since Foundry's vm.mockCall uses last-registered-wins for the same address+selector, - // and encrypted deposits are processed sequentially, we can't differentiate two calls - // to the same precompile with different expected outputs using selector-only mocking. - // - // Workaround: mock both precompiles to return bobRecipient's plaintext. - // Alice's deposit will fail the plaintext check (dec.to != decryptedTo), causing a bounce. - // We test a simpler scenario: mock for aliceRecipient so BOTH succeed with the same plaintext. - // - // Actually, the cleanest approach: make both deposits decrypt to the same recipient/memo. - // This tests key rotation without needing differentiated mocks. - - // Use same recipient/memo for both decryptions + // Mock precompiles to return the same plaintext for both deposits. + // Since vm.mockCall with just the selector matches ALL calls, both encrypted + // deposits will decrypt to the same (sharedRecipient, sharedMemo). address sharedRecipient = address(0x700); bytes32 sharedMemo = bytes32("shared-secret"); - decs[0].to = sharedRecipient; - decs[0].memo = sharedMemo; - decs[1].to = sharedRecipient; - decs[1].memo = sharedMemo; vm.etch(CHAUM_PEDERSEN_VERIFY, hex"00"); vm.etch(AES_GCM_DECRYPT, hex"00"); diff --git a/docs/specs/test/zone/ZoneInbox.t.sol b/docs/specs/test/zone/ZoneInbox.t.sol index 1774e7f12..f1680a88d 100644 --- a/docs/specs/test/zone/ZoneInbox.t.sol +++ b/docs/specs/test/zone/ZoneInbox.t.sol @@ -495,8 +495,6 @@ contract ZoneInboxTest is Test { decs[0] = DecryptionData({ sharedSecret: bytes32(uint256(0xdeadbeef)), sharedSecretYParity: 0x02, - to: recipient, - memo: memo, cpProof: ChaumPedersenProof({ s: bytes32(uint256(1)), c: bytes32(uint256(2)) }) }); @@ -548,8 +546,6 @@ contract ZoneInboxTest is Test { decs[0] = DecryptionData({ sharedSecret: bytes32(uint256(0xdeadbeef)), sharedSecretYParity: 0x02, - to: address(0x500), - memo: bytes32("memo"), cpProof: ChaumPedersenProof({ s: bytes32(uint256(1)), c: bytes32(uint256(2)) }) }); @@ -595,8 +591,6 @@ contract ZoneInboxTest is Test { decs[0] = DecryptionData({ sharedSecret: bytes32(uint256(0xabcd)), sharedSecretYParity: 0x02, - to: recipient, - memo: encMemo, cpProof: ChaumPedersenProof({ s: bytes32(uint256(1)), c: bytes32(uint256(2)) }) }); @@ -653,8 +647,6 @@ contract ZoneInboxTest is Test { decs[0] = DecryptionData({ sharedSecret: bytes32(uint256(1)), sharedSecretYParity: 0x02, - to: address(0x500), - memo: bytes32("memo"), cpProof: ChaumPedersenProof({ s: bytes32(uint256(1)), c: bytes32(uint256(2)) }) }); @@ -781,8 +773,6 @@ contract ZoneInboxTest is Test { decs[0] = DecryptionData({ sharedSecret: bytes32(uint256(0xbad)), sharedSecretYParity: 0x02, - to: address(0x500), - memo: bytes32("memo"), cpProof: ChaumPedersenProof({ s: bytes32(uint256(1)), c: bytes32(uint256(2)) }) }); @@ -798,9 +788,7 @@ contract ZoneInboxTest is Test { /// @notice Helper: set up an encrypted deposit flow where AES-GCM returns a specific plaintext function _setupEncryptedDepositWithPlaintext( bytes memory mockPlaintext, - bool aesValid, - address recipient, - bytes32 memo + bool aesValid ) internal returns (QueuedDeposit[] memory deposits, DecryptionData[] memory decs) @@ -844,8 +832,6 @@ contract ZoneInboxTest is Test { decs[0] = DecryptionData({ sharedSecret: bytes32(uint256(0xdeadbeef)), sharedSecretYParity: 0x02, - to: recipient, - memo: memo, cpProof: ChaumPedersenProof({ s: bytes32(uint256(1)), c: bytes32(uint256(2)) }) }); } @@ -865,7 +851,7 @@ contract ZoneInboxTest is Test { } (QueuedDeposit[] memory deposits, DecryptionData[] memory decs) = - _setupEncryptedDepositWithPlaintext(shortPlaintext, true, recipient, memo); + _setupEncryptedDepositWithPlaintext(shortPlaintext, true); vm.prank(sequencer); inbox.advanceTempo("", deposits, decs, new EnabledToken[](0)); @@ -888,7 +874,7 @@ contract ZoneInboxTest is Test { } (QueuedDeposit[] memory deposits, DecryptionData[] memory decs) = - _setupEncryptedDepositWithPlaintext(longPlaintext, true, recipient, memo); + _setupEncryptedDepositWithPlaintext(longPlaintext, true); vm.prank(sequencer); inbox.advanceTempo("", deposits, decs, new EnabledToken[](0)); @@ -906,7 +892,7 @@ contract ZoneInboxTest is Test { bytes memory emptyPlaintext = new bytes(0); (QueuedDeposit[] memory deposits, DecryptionData[] memory decs) = - _setupEncryptedDepositWithPlaintext(emptyPlaintext, true, recipient, memo); + _setupEncryptedDepositWithPlaintext(emptyPlaintext, true); vm.prank(sequencer); inbox.advanceTempo("", deposits, decs, new EnabledToken[](0)); @@ -925,7 +911,7 @@ contract ZoneInboxTest is Test { bytes memory correctPlaintext = EncryptedDepositLib.encodePlaintext(recipient, memo); (QueuedDeposit[] memory deposits, DecryptionData[] memory decs) = - _setupEncryptedDepositWithPlaintext(correctPlaintext, true, recipient, memo); + _setupEncryptedDepositWithPlaintext(correctPlaintext, true); vm.prank(sequencer); inbox.advanceTempo("", deposits, decs, new EnabledToken[](0)); diff --git a/docs/specs/zone_spec.md b/docs/specs/zone_spec.md index 1fe7e2ba3..6c9720710 100644 --- a/docs/specs/zone_spec.md +++ b/docs/specs/zone_spec.md @@ -351,17 +351,15 @@ Deposits are processed in the exact order they were made, regardless of type. ### Onchain Decryption Verification -When the sequencer processes an encrypted deposit on the zone, it claims the ciphertext decrypts to a specific `(to, memo)`. The zone verifies this onchain without the sequencer revealing their private key. +When the sequencer processes an encrypted deposit on the zone, the zone recovers the recipient and memo from the ciphertext onchain without the sequencer revealing their private key or supplying the plaintext. -The sequencer provides the ECDH shared secret alongside the decrypted data. Verification proceeds in three steps: +The sequencer provides the ECDH shared secret alongside a proof of its correct derivation. Verification proceeds in two steps: 1. **Chaum-Pedersen proof.** The sequencer provides a zero-knowledge proof that the shared secret was correctly derived: "I know `privSeq` such that `pubSeq = privSeq * G` AND `sharedSecretPoint = privSeq * ephemeralPub`." The [Chaum-Pedersen Verify](#chaum-pedersen-verify) precompile checks this proof. The sequencer's public key is looked up from the onchain key history, not supplied by the sequencer, preventing key substitution. -2. **AES-GCM decryption.** The zone derives an AES-256 key from the shared secret using HKDF-SHA256 (implemented in Solidity using the SHA256 precompile at `0x02`). The HKDF info string includes `tempoPortal`, `keyIndex`, and `ephemeralPubkeyX` for domain separation. The [AES-GCM Decrypt](#aes-gcm-decrypt) precompile decrypts the ciphertext and validates the GCM authentication tag. +2. **AES-GCM decryption.** The zone derives an AES-256 key from the shared secret using HKDF-SHA256 (implemented in Solidity using the SHA256 precompile at `0x02`). The HKDF info string includes `tempoPortal`, `keyIndex`, and `ephemeralPubkeyX` for domain separation. The [AES-GCM Decrypt](#aes-gcm-decrypt) precompile decrypts the ciphertext and validates the GCM authentication tag. The plaintext is packed as `[address (20 bytes)][memo (32 bytes)][padding (12 bytes)]` totaling 64 bytes; the zone parses `(to, memo)` directly from it and uses those values for the mint. -3. **Plaintext validation.** The zone confirms the decrypted plaintext matches the `(to, memo)` the sequencer claimed. The plaintext is packed as `[address (20 bytes)][memo (32 bytes)][padding (12 bytes)]` totaling 64 bytes. - -If any step fails (invalid proof, GCM tag mismatch, plaintext mismatch), the zone mints the tokens to the sender's address on the zone instead. The Tempo-side funds remain locked in the portal. This ensures chain progress is never blocked by invalid encrypted deposits. +If either step fails (invalid proof or GCM tag mismatch), the zone mints the tokens to the sender's address on the zone instead. The Tempo-side funds remain locked in the portal. This ensures chain progress is never blocked by invalid encrypted deposits. Because `(to, memo)` are derived from the decrypted plaintext rather than supplied by the sequencer, there is no separate plaintext-mismatch check and the sequencer cannot redirect a valid ciphertext to a different recipient onchain. The Chaum-Pedersen proof also prevents griefing. Without it, a user could submit garbage ciphertext that the sequencer cannot decrypt and cannot prove invalid, blocking the chain. The proof lets the sequencer demonstrate correct shared secret derivation, and the GCM tag failure then proves the ciphertext itself was invalid. @@ -981,8 +979,6 @@ struct EncryptedDepositPayload { struct DecryptionData { bytes32 sharedSecret; uint8 sharedSecretYParity; - address to; - bytes32 memo; ChaumPedersenProof cpProof; }