Contract Address Details
contract
0x6DC852a4949E0deeD6b892d266169B4f16EE093b
Sponsored:
- Contract name:
- PolygonZkEVMGlobalExitRootV2
- Optimization enabled
- true
- Compiler version
- v0.8.20+commit.a1b79de6
- Optimization runs
- 999999
- Verified at
- 2025-01-22T04:21:54.224276Z
Constructor Arguments
0000000000000000000000009d2dcf86e9ca815ba0010bf9644b488ad0dc39580000000000000000000000007376998677f02ed611ff976b9d7f19b193951bde
Arg [0] (address) : 0x9d2dcf86e9ca815ba0010bf9644b488ad0dc3958
Arg [1] (address) : 0x7376998677f02ed611ff976b9d7f19b193951bde
contracts/v2/PolygonZkEVMGlobalExitRootV2.sol
// SPDX-License-Identifier: AGPL-3.0 pragma solidity 0.8.20; import "./interfaces/IPolygonZkEVMGlobalExitRootV2.sol"; import "./lib/PolygonZkEVMGlobalExitRootBaseStorage.sol"; import "../lib/GlobalExitRootLib.sol"; import "./lib/DepositContractBase.sol"; /** * Contract responsible for managing the exit roots across multiple networks */ contract PolygonZkEVMGlobalExitRootV2 is PolygonZkEVMGlobalExitRootBaseStorage, DepositContractBase { // PolygonZkEVMBridge address address public immutable bridgeAddress; // Rollup manager contract address address public immutable rollupManager; /** * @dev Emitted when the global exit root is updated */ event UpdateL1InfoTree( bytes32 indexed mainnetExitRoot, bytes32 indexed rollupExitRoot ); /** * @param _rollupManager Rollup manager contract address * @param _bridgeAddress PolygonZkEVMBridge contract address */ constructor(address _rollupManager, address _bridgeAddress) { rollupManager = _rollupManager; bridgeAddress = _bridgeAddress; } /** * @notice Update the exit root of one of the networks and the global exit root * @param newRoot new exit tree root */ function updateExitRoot(bytes32 newRoot) external { // Store storage variables into temporal variables since will be used multiple times bytes32 cacheLastRollupExitRoot; bytes32 cacheLastMainnetExitRoot; if (msg.sender == bridgeAddress) { lastMainnetExitRoot = newRoot; cacheLastMainnetExitRoot = newRoot; cacheLastRollupExitRoot = lastRollupExitRoot; } else if (msg.sender == rollupManager) { lastRollupExitRoot = newRoot; cacheLastRollupExitRoot = newRoot; cacheLastMainnetExitRoot = lastMainnetExitRoot; } else { revert OnlyAllowedContracts(); } bytes32 newGlobalExitRoot = GlobalExitRootLib.calculateGlobalExitRoot( cacheLastMainnetExitRoot, cacheLastRollupExitRoot ); // If it already exists, do not modify the blockhash if (globalExitRootMap[newGlobalExitRoot] == 0) { uint256 lastBlockHash = uint256(blockhash(block.number - 1)); globalExitRootMap[newGlobalExitRoot] = lastBlockHash; // save new leaf in L1InfoTree _addLeaf( getLeafValue( newGlobalExitRoot, lastBlockHash, uint64(block.timestamp) ) ); emit UpdateL1InfoTree( cacheLastMainnetExitRoot, cacheLastRollupExitRoot ); } } /** * @notice Return last global exit root */ function getLastGlobalExitRoot() public view returns (bytes32) { return GlobalExitRootLib.calculateGlobalExitRoot( lastMainnetExitRoot, lastRollupExitRoot ); } /** * @notice Computes and returns the merkle root of the L1InfoTree */ function getRoot() public view override(DepositContractBase, IPolygonZkEVMGlobalExitRootV2) returns (bytes32) { return super.getRoot(); } /** * @notice Given the leaf data returns the leaf hash * @param newGlobalExitRoot Last global exit root * @param lastBlockHash Last accesible block hash * @param timestamp Ethereum timestamp in seconds */ function getLeafValue( bytes32 newGlobalExitRoot, uint256 lastBlockHash, uint64 timestamp ) public pure returns (bytes32) { return keccak256( abi.encodePacked(newGlobalExitRoot, lastBlockHash, timestamp) ); } }
contracts/interfaces/IBasePolygonZkEVMGlobalExitRoot.sol
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.20; interface IBasePolygonZkEVMGlobalExitRoot { /** * @dev Thrown when the caller is not the allowed contracts */ error OnlyAllowedContracts(); function updateExitRoot(bytes32 newRollupExitRoot) external; function globalExitRootMap( bytes32 globalExitRootNum ) external returns (uint256); }
contracts/lib/GlobalExitRootLib.sol
// SPDX-License-Identifier: AGPL-3.0 pragma solidity 0.8.20; /** * @dev A library that provides the necessary calculations to calculate the global exit root */ library GlobalExitRootLib { function calculateGlobalExitRoot( bytes32 mainnetExitRoot, bytes32 rollupExitRoot ) internal pure returns (bytes32) { return keccak256(abi.encodePacked(mainnetExitRoot, rollupExitRoot)); } }
contracts/v2/interfaces/IPolygonZkEVMGlobalExitRootV2.sol
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.20; import "../../interfaces/IBasePolygonZkEVMGlobalExitRoot.sol"; interface IPolygonZkEVMGlobalExitRootV2 is IBasePolygonZkEVMGlobalExitRoot { function getLastGlobalExitRoot() external view returns (bytes32); function getRoot() external view returns (bytes32); }
contracts/v2/lib/DepositContractBase.sol
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.20; /** * This contract will be used as a helper for all the sparse merkle tree related functions * Based on the implementation of the deposit eth2.0 contract https://github.com/ethereum/consensus-specs/blob/dev/solidity_deposit_contract/deposit_contract.sol */ contract DepositContractBase { /** * @dev Thrown when the merkle tree is full */ error MerkleTreeFull(); // Merkle tree levels uint256 internal constant _DEPOSIT_CONTRACT_TREE_DEPTH = 32; // This ensures `depositCount` will fit into 32-bits uint256 internal constant _MAX_DEPOSIT_COUNT = 2 ** _DEPOSIT_CONTRACT_TREE_DEPTH - 1; // Branch array which contains the necessary sibilings to compute the next root when a new // leaf is inserted bytes32[_DEPOSIT_CONTRACT_TREE_DEPTH] internal _branch; // Counter of current deposits uint256 public depositCount; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. */ uint256[10] private _gap; /** * @notice Computes and returns the merkle root */ function getRoot() public view virtual returns (bytes32) { bytes32 node; uint256 size = depositCount; bytes32 currentZeroHashHeight = 0; for ( uint256 height = 0; height < _DEPOSIT_CONTRACT_TREE_DEPTH; height++ ) { if (((size >> height) & 1) == 1) node = keccak256(abi.encodePacked(_branch[height], node)); else node = keccak256(abi.encodePacked(node, currentZeroHashHeight)); currentZeroHashHeight = keccak256( abi.encodePacked(currentZeroHashHeight, currentZeroHashHeight) ); } return node; } /** * @notice Add a new leaf to the merkle tree * @param leaf Leaf */ function _addLeaf(bytes32 leaf) internal { bytes32 node = leaf; // Avoid overflowing the Merkle tree (and prevent edge case in computing `_branch`) if (depositCount >= _MAX_DEPOSIT_COUNT) { revert MerkleTreeFull(); } // Add deposit data root to Merkle tree (update a single `_branch` node) uint256 size = ++depositCount; for ( uint256 height = 0; height < _DEPOSIT_CONTRACT_TREE_DEPTH; height++ ) { if (((size >> height) & 1) == 1) { _branch[height] = node; return; } node = keccak256(abi.encodePacked(_branch[height], node)); } // As the loop should always end prematurely with the `return` statement, // this code should be unreachable. We assert `false` just to be safe. assert(false); } /** * @notice Verify merkle proof * @param leafHash Leaf hash * @param smtProof Smt proof * @param index Index of the leaf * @param root Merkle root */ function verifyMerkleProof( bytes32 leafHash, bytes32[_DEPOSIT_CONTRACT_TREE_DEPTH] calldata smtProof, uint32 index, bytes32 root ) public pure returns (bool) { return calculateRoot(leafHash, smtProof, index) == root; } /** * @notice Calculate root from merkle proof * @param leafHash Leaf hash * @param smtProof Smt proof * @param index Index of the leaf */ function calculateRoot( bytes32 leafHash, bytes32[_DEPOSIT_CONTRACT_TREE_DEPTH] calldata smtProof, uint32 index ) public pure returns (bytes32) { bytes32 node = leafHash; // Compute root for ( uint256 height = 0; height < _DEPOSIT_CONTRACT_TREE_DEPTH; height++ ) { if (((index >> height) & 1) == 1) node = keccak256(abi.encodePacked(smtProof[height], node)); else node = keccak256(abi.encodePacked(node, smtProof[height])); } return node; } }
contracts/v2/lib/PolygonZkEVMGlobalExitRootBaseStorage.sol
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.20; import "../interfaces/IPolygonZkEVMGlobalExitRootV2.sol"; /** * Since the current contract of PolygonZkEVMGlobalExitRoot will be upgraded to a PolygonZkEVMGlobalExitRootV2, and it will implement * the DepositContractBase, this base is needed to preserve the previous storage slots */ abstract contract PolygonZkEVMGlobalExitRootBaseStorage is IPolygonZkEVMGlobalExitRootV2 { // Rollup root, contains all exit roots of all rollups bytes32 public lastRollupExitRoot; // Mainnet exit root, this will be updated every time a deposit is made in mainnet bytes32 public lastMainnetExitRoot; // Store every global exit root: Root --> blockhash // Note that previously recoded global exit roots in previous versions, timestamp was recorded instead of blockhash mapping(bytes32 => uint256) public globalExitRootMap; }
Compiler Settings
{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata","storageLayout"],"":["ast"]}},"optimizer":{"runs":999999,"enabled":true},"libraries":{},"evmVersion":"paris"}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_rollupManager","internalType":"address"},{"type":"address","name":"_bridgeAddress","internalType":"address"}]},{"type":"error","name":"MerkleTreeFull","inputs":[]},{"type":"error","name":"OnlyAllowedContracts","inputs":[]},{"type":"event","name":"UpdateL1InfoTree","inputs":[{"type":"bytes32","name":"mainnetExitRoot","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"rollupExitRoot","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"bridgeAddress","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"calculateRoot","inputs":[{"type":"bytes32","name":"leafHash","internalType":"bytes32"},{"type":"bytes32[32]","name":"smtProof","internalType":"bytes32[32]"},{"type":"uint32","name":"index","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"depositCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getLastGlobalExitRoot","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getLeafValue","inputs":[{"type":"bytes32","name":"newGlobalExitRoot","internalType":"bytes32"},{"type":"uint256","name":"lastBlockHash","internalType":"uint256"},{"type":"uint64","name":"timestamp","internalType":"uint64"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getRoot","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"globalExitRootMap","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"lastMainnetExitRoot","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"lastRollupExitRoot","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"rollupManager","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateExitRoot","inputs":[{"type":"bytes32","name":"newRoot","internalType":"bytes32"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"verifyMerkleProof","inputs":[{"type":"bytes32","name":"leafHash","internalType":"bytes32"},{"type":"bytes32[32]","name":"smtProof","internalType":"bytes32[32]"},{"type":"uint32","name":"index","internalType":"uint32"},{"type":"bytes32","name":"root","internalType":"bytes32"}]}]
Contract Creation Code
0x60c060405234801561001057600080fd5b50604051610b3c380380610b3c83398101604081905261002f91610062565b6001600160a01b0391821660a05216608052610095565b80516001600160a01b038116811461005d57600080fd5b919050565b6000806040838503121561007557600080fd5b61007e83610046565b915061008c60208401610046565b90509250929050565b60805160a051610a746100c86000396000818161014901526102c401526000818161021801526102770152610a746000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c806349b7b8021161008157806383f244031161005b57806383f2440314610200578063a3c573eb14610213578063fb5708341461023a57600080fd5b806349b7b802146101445780635ca1e165146101905780635d8105011461019857600080fd5b8063319cf735116100b2578063319cf7351461011e57806333d6247d146101275780633ed691ef1461013c57600080fd5b806301fd9044146100d9578063257b3632146100f55780632dfdf0b514610115575b600080fd5b6100e260005481565b6040519081526020015b60405180910390f35b6100e2610103366004610722565b60026020526000908152604090205481565b6100e260235481565b6100e260015481565b61013a610135366004610722565b61025d565b005b6100e2610406565b61016b7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ec565b6100e261041b565b6100e26101a636600461073b565b604080516020808201959095528082019390935260c09190911b7fffffffffffffffff0000000000000000000000000000000000000000000000001660608301528051604881840301815260689092019052805191012090565b6100e261020e3660046107ac565b610425565b61016b7f000000000000000000000000000000000000000000000000000000000000000081565b61024d6102483660046107eb565b6104fb565b60405190151581526020016100ec565b60008073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633036102ad57505060018190556000548161032d565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633036102fb5750506000819055600154819061032d565b6040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103398284610513565b6000818152600260205260408120549192500361040057600061035d600143610862565b60008381526002602090815260409182902092409283905581518082018690528083018490527fffffffffffffffff0000000000000000000000000000000000000000000000004260c01b16606082015282518082036048018152606890910190925281519101209091506103d190610542565b604051849084907fda61aa7823fcd807e37b95aabcbe17f03a6f3efd514176444dae191d27fd66b390600090a3505b50505050565b6000610416600154600054610513565b905090565b6000610416610645565b600083815b60208110156104f257600163ffffffff8516821c811690036104955784816020811061045857610458610875565b602002013582604051602001610478929190918252602082015260400190565b6040516020818303038152906040528051906020012091506104e0565b818582602081106104a8576104a8610875565b60200201356040516020016104c7929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b806104ea816108a4565b91505061042a565b50949350505050565b600081610509868686610425565b1495945050505050565b604080516020808201859052818301849052825180830384018152606090920190925280519101205b92915050565b806001610551602060026109fc565b61055b9190610862565b60235410610595576040517fef5ccf6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006023600081546105a6906108a4565b9182905550905060005b6020811015610637578082901c6001166001036105e35782600382602081106105db576105db610875565b015550505050565b600381602081106105f6576105f6610875565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250808061062f906108a4565b9150506105b0565b50610640610a0f565b505050565b602354600090819081805b6020811015610719578083901c6001166001036106ad576003816020811061067a5761067a610875565b015460408051602081019290925281018590526060016040516020818303038152906040528051906020012093506106da565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b60408051602081018490529081018390526060016040516020818303038152906040528051906020012091508080610711906108a4565b915050610650565b50919392505050565b60006020828403121561073457600080fd5b5035919050565b60008060006060848603121561075057600080fd5b8335925060208401359150604084013567ffffffffffffffff8116811461077657600080fd5b809150509250925092565b80610400810183101561053c57600080fd5b803563ffffffff811681146107a757600080fd5b919050565b600080600061044084860312156107c257600080fd5b833592506107d38560208601610781565b91506107e26104208501610793565b90509250925092565b600080600080610460858703121561080257600080fd5b843593506108138660208701610781565b92506108226104208601610793565b939692955092936104400135925050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561053c5761053c610833565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036108d5576108d5610833565b5060010190565b600181815b8085111561093557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561091b5761091b610833565b8085161561092857918102915b93841c93908002906108e1565b509250929050565b60008261094c5750600161053c565b816109595750600061053c565b816001811461096f576002811461097957610995565b600191505061053c565b60ff84111561098a5761098a610833565b50506001821b61053c565b5060208310610133831016604e8410600b84101617156109b8575081810a61053c565b6109c283836108dc565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156109f4576109f4610833565b029392505050565b6000610a08838361093d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea2646970667358221220dbd1e7b3ff384ef35ee296421e7bc2bb2c5279b9abce68d63bcc855e92d1bdc264736f6c634300081400330000000000000000000000009d2dcf86e9ca815ba0010bf9644b488ad0dc39580000000000000000000000007376998677f02ed611ff976b9d7f19b193951bde
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106100d45760003560e01c806349b7b8021161008157806383f244031161005b57806383f2440314610200578063a3c573eb14610213578063fb5708341461023a57600080fd5b806349b7b802146101445780635ca1e165146101905780635d8105011461019857600080fd5b8063319cf735116100b2578063319cf7351461011e57806333d6247d146101275780633ed691ef1461013c57600080fd5b806301fd9044146100d9578063257b3632146100f55780632dfdf0b514610115575b600080fd5b6100e260005481565b6040519081526020015b60405180910390f35b6100e2610103366004610722565b60026020526000908152604090205481565b6100e260235481565b6100e260015481565b61013a610135366004610722565b61025d565b005b6100e2610406565b61016b7f0000000000000000000000009d2dcf86e9ca815ba0010bf9644b488ad0dc395881565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ec565b6100e261041b565b6100e26101a636600461073b565b604080516020808201959095528082019390935260c09190911b7fffffffffffffffff0000000000000000000000000000000000000000000000001660608301528051604881840301815260689092019052805191012090565b6100e261020e3660046107ac565b610425565b61016b7f0000000000000000000000007376998677f02ed611ff976b9d7f19b193951bde81565b61024d6102483660046107eb565b6104fb565b60405190151581526020016100ec565b60008073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007376998677f02ed611ff976b9d7f19b193951bde1633036102ad57505060018190556000548161032d565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000009d2dcf86e9ca815ba0010bf9644b488ad0dc39581633036102fb5750506000819055600154819061032d565b6040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006103398284610513565b6000818152600260205260408120549192500361040057600061035d600143610862565b60008381526002602090815260409182902092409283905581518082018690528083018490527fffffffffffffffff0000000000000000000000000000000000000000000000004260c01b16606082015282518082036048018152606890910190925281519101209091506103d190610542565b604051849084907fda61aa7823fcd807e37b95aabcbe17f03a6f3efd514176444dae191d27fd66b390600090a3505b50505050565b6000610416600154600054610513565b905090565b6000610416610645565b600083815b60208110156104f257600163ffffffff8516821c811690036104955784816020811061045857610458610875565b602002013582604051602001610478929190918252602082015260400190565b6040516020818303038152906040528051906020012091506104e0565b818582602081106104a8576104a8610875565b60200201356040516020016104c7929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b806104ea816108a4565b91505061042a565b50949350505050565b600081610509868686610425565b1495945050505050565b604080516020808201859052818301849052825180830384018152606090920190925280519101205b92915050565b806001610551602060026109fc565b61055b9190610862565b60235410610595576040517fef5ccf6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006023600081546105a6906108a4565b9182905550905060005b6020811015610637578082901c6001166001036105e35782600382602081106105db576105db610875565b015550505050565b600381602081106105f6576105f6610875565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250808061062f906108a4565b9150506105b0565b50610640610a0f565b505050565b602354600090819081805b6020811015610719578083901c6001166001036106ad576003816020811061067a5761067a610875565b015460408051602081019290925281018590526060016040516020818303038152906040528051906020012093506106da565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b60408051602081018490529081018390526060016040516020818303038152906040528051906020012091508080610711906108a4565b915050610650565b50919392505050565b60006020828403121561073457600080fd5b5035919050565b60008060006060848603121561075057600080fd5b8335925060208401359150604084013567ffffffffffffffff8116811461077657600080fd5b809150509250925092565b80610400810183101561053c57600080fd5b803563ffffffff811681146107a757600080fd5b919050565b600080600061044084860312156107c257600080fd5b833592506107d38560208601610781565b91506107e26104208501610793565b90509250925092565b600080600080610460858703121561080257600080fd5b843593506108138660208701610781565b92506108226104208601610793565b939692955092936104400135925050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561053c5761053c610833565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036108d5576108d5610833565b5060010190565b600181815b8085111561093557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561091b5761091b610833565b8085161561092857918102915b93841c93908002906108e1565b509250929050565b60008261094c5750600161053c565b816109595750600061053c565b816001811461096f576002811461097957610995565b600191505061053c565b60ff84111561098a5761098a610833565b50506001821b61053c565b5060208310610133831016604e8410600b84101617156109b8575081810a61053c565b6109c283836108dc565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156109f4576109f4610833565b029392505050565b6000610a08838361093d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfea2646970667358221220dbd1e7b3ff384ef35ee296421e7bc2bb2c5279b9abce68d63bcc855e92d1bdc264736f6c63430008140033