Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- DepositContract
- Optimization enabled
- true
- Compiler version
- v0.8.16+commit.07a7930e
- Optimization runs
- 200
- EVM Version
- london
- Verified at
- 2025-07-15T13:59:15.758126Z
DepositContract.sol
// ┏━━━┓━┏┓━━━━━━━━━┏━━━┓━━━━━━━━━━━━━━━━━━━┏┓━━━━━┏━━━┓━━━━━━━━━┏┓━━━━━━━━━━━━━━┏┓━
// ┃┏━━┛┏┛┗┓━━━━━━━━┗┓┏┓┃━━━━━━━━━━━━━━━━━━┏┛┗┓━━━━┃┏━┓┃━━━━━━━━┏┛┗┓━━━━━━━━━━━━┏┛┗┓
// ┃┗━━┓┗┓┏┛┏━┓━━━━━━┃┃┃┃┏━━┓┏━━┓┏━━┓┏━━┓┏┓┗┓┏┛━━━━┃┃━┗┛┏━━┓┏━┓━┗┓┏┛┏━┓┏━━┓━┏━━┓┗┓┏┛
// ┃┏━━┛━┃┃━┃┏┓┓━━━━━┃┃┃┃┃┏┓┃┃┏┓┃┃┏┓┃┃━━┫┣┫━┃┃━━━━━┃┃━┏┓┃┏┓┃┃┏┓┓━┃┃━┃┏┛┗━┓┃━┃┏━┛━┃┃━
// ┃┃━━━━┃┗┓┃┃┃┃━━━━┏┛┗┛┃┃┃━┫┃┗┛┃┃┗┛┃┣━━┃┃┃━┃┗┓━━━━┃┗━┛┃┃┗┛┃┃┃┃┃━┃┗┓┃┃━┃┗┛┗┓┃┗━┓━┃┗┓
// ┗┛━━━━┗━┛┗┛┗┛━━━━┗━━━┛┗━━┛┃┏━┛┗━━┛┗━━┛┗┛━┗━┛━━━━┗━━━┛┗━━┛┗┛┗┛━┗━┛┗┛━┗━━━┛┗━━┛━┗━┛
// ━━━━━━━━━━━━━━━━━━━━━━━━━━┃┃━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// ━━━━━━━━━━━━━━━━━━━━━━━━━━┗┛━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.16;
// Based on official specification in https://eips.ethereum.org/EIPS/eip-165
interface ERC165 {
/// @notice Query if a contract implements an interface
/// @param interfaceId The interface identifier, as specified in ERC-165
/// @dev Interface identification is specified in ERC-165. This function uses less than 30,000 gas.
/// @return `true` if the contract implements `interfaceId` and `interfaceId` is not 0xffffffff, `false` otherwise
function supportsInterface(bytes4 interfaceId) external pure returns (bool);
}
/// @notice This is the FastexChain(Bahamut) deposit contract interface.
interface IDepositContract {
/// @notice A processed deposit event.
event DepositEvent(
bytes pubkey,
bytes withdrawal_credentials,
bytes contract_address,
bytes amount,
bytes signature,
bytes index
);
/**
* @notice Submit a DepositData object.
* @param pubkey A BLS12-381 public key.
* @param withdrawal_credentials Commitment to a public key for withdrawals.
* @param contract_address Address of the smart contract that a associated with this deposit.
* @param signature A BLS12-381 signature.
* @param deposit_data_root The SHA-256 hash of the SSZ-encoded DepositData object.
*/
function deposit(
bytes calldata pubkey,
bytes calldata withdrawal_credentials,
bytes calldata contract_address,
bytes calldata signature,
bytes32 deposit_data_root
) external payable;
/**
* @notice Changes contract ownership
* @param contract_address Address of the smart contract which ownership need to transfer
* @param new_owner_address New owner address
*/
function transfer_contract_ownership(address contract_address, address new_owner_address) external;
/**
* @notice Query the owner of the given contract
* @return The owner of the contract
*/
function get_contract_owner(address contract_address) external view returns (address);
/**
* @notice Query the current deposit root hash.
* @return The deposit root hash.
*/
function get_deposit_root() external view returns (bytes32);
/**
* @notice Query the current deposit count.
* @return The deposit count encoded as a little endian 64-bit number.
*/
function get_deposit_count() external view returns (bytes memory);
}
/// @notice This is the FastexChain(Bahamut) deposit contract interface.
contract DepositContract is IDepositContract, ERC165 {
uint256 private constant DEPOSIT_CONTRACT_TREE_DEPTH = 32;
// NOTE: this also ensures `deposit_count` will fit into 64-bits
uint256 private constant MAX_DEPOSIT_COUNT = 2**DEPOSIT_CONTRACT_TREE_DEPTH - 1;
bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] private branch;
uint256 private deposit_count;
bytes32[DEPOSIT_CONTRACT_TREE_DEPTH] private zero_hashes;
address private deployer_getter = 0x1000000000000000000000000000000000000002;
mapping (address => address) private contract_owners;
constructor() {
// Compute hashes in empty sparse Merkle tree
for (uint256 height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH - 1; height++) {
zero_hashes[height + 1] = sha256(abi.encodePacked(zero_hashes[height], zero_hashes[height]));
}
}
function get_deposit_root() override external view returns (bytes32) {
bytes32 node;
uint256 size = deposit_count;
for (uint256 height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {
if ((size & 1) == 1)
node = sha256(abi.encodePacked(branch[height], node));
else
node = sha256(abi.encodePacked(node, zero_hashes[height]));
size /= 2;
}
return sha256(abi.encodePacked(
node,
_to_little_endian_64(uint64(deposit_count)),
bytes24(0)
));
}
function get_deposit_count() override external view returns (bytes memory) {
return _to_little_endian_64(uint64(deposit_count));
}
function transfer_contract_ownership(address contract_address, address new_owner_address) override external {
require(address(0x0) != contract_address, 'DepositContract: Contract address cannot be null');
require(address(0x0) != new_owner_address, 'DepositContract: Owner address cannot be null');
require(msg.sender == get_contract_owner(contract_address), 'DepositContract: Only owner can transfer ownership');
contract_owners[contract_address] = new_owner_address;
}
function deposit(
bytes calldata pubkey,
bytes calldata withdrawal_credentials,
bytes calldata contract_address,
bytes calldata signature,
bytes32 deposit_data_root
) override external payable {
// Extended ABI length checks since dynamic types are used.
require(pubkey.length == 48, "DepositContract: invalid pubkey length");
require(withdrawal_credentials.length == 32, "DepositContract: invalid withdrawal_credentials length");
require(contract_address.length == 20, "DepositContract: invalid withdrawal_credentials length");
require(signature.length == 96, "DepositContract: invalid signature length");
// Check deposit amount
address c_address = _to_address(contract_address);
if (address(0x0) != c_address) {
require(get_contract_owner(c_address) == msg.sender, "DepositContract: sender should be owner of contract");
}
require(msg.value >= 256 ether, "DepositContract: deposit value too low");
require(msg.value % 1 gwei == 0, "DepositContract: deposit value not multiple of gwei");
uint256 deposit_amount = msg.value / 1 gwei;
require(deposit_amount <= type(uint64).max, "DepositContract: deposit value too high");
// Emit `DepositEvent` log
bytes memory amount = _to_little_endian_64(uint64(deposit_amount));
emit DepositEvent(
pubkey,
withdrawal_credentials,
contract_address,
amount,
signature,
_to_little_endian_64(uint64(deposit_count))
);
// Compute deposit data root (`DepositData` hash tree root)
bytes32 root = _calculate_root(
pubkey,
withdrawal_credentials,
contract_address,
amount,
signature);
// Verify computed and expected deposit data roots match
require(root == deposit_data_root, "DepositContract: reconstructed DepositData does not match supplied deposit_data_root");
// Avoid overflowing the Merkle tree (and prevent edge case in computing `branch`)
require(deposit_count < MAX_DEPOSIT_COUNT, "DepositContract: merkle tree full");
// Add deposit data root to Merkle tree (update a single `branch` node)
deposit_count += 1;
_update_branch(root);
}
function supportsInterface(bytes4 interfaceId) override external pure returns (bool) {
return interfaceId == type(ERC165).interfaceId || interfaceId == type(IDepositContract).interfaceId;
}
function get_contract_owner(address contract_address) override public view returns (address) {
if (address(0x0) != contract_owners[contract_address]) {
return contract_owners[contract_address];
}
(bool success, bytes memory deployer) = deployer_getter.staticcall(abi.encodePacked(contract_address));
require(success, 'DepositContract: Cannot get deployer');
return _to_address(deployer);
}
/// Helper member functions
function _to_address(bytes memory addr) private pure returns (address ret_address) {
assembly {
ret_address := mload(add(addr, 20))
}
}
function _to_little_endian_64(uint64 value) private pure returns (bytes memory ret) {
ret = new bytes(8);
bytes8 bytesValue = bytes8(value);
// Byteswapping during copying to bytes.
ret[0] = bytesValue[7];
ret[1] = bytesValue[6];
ret[2] = bytesValue[5];
ret[3] = bytesValue[4];
ret[4] = bytesValue[3];
ret[5] = bytesValue[2];
ret[6] = bytesValue[1];
ret[7] = bytesValue[0];
}
function _calculate_root(
bytes calldata pubkey,
bytes calldata withdrawal_credentials,
bytes calldata contract_address,
bytes memory amount,
bytes calldata signature)
pure
private
returns(bytes32) {
bytes32 pubkey_root = sha256(abi.encodePacked(pubkey, bytes16(0)));
bytes32 signature_root = sha256(abi.encodePacked(
sha256(abi.encodePacked(signature[:64])),
sha256(abi.encodePacked(signature[64:], bytes32(0)))
));
bytes32 node1 = sha256(abi.encodePacked(pubkey_root, withdrawal_credentials));
bytes32 node2 = sha256(abi.encodePacked(contract_address, bytes12(0), amount, bytes24(0)));
bytes32 node3 = sha256(abi.encodePacked(signature_root, bytes32(0)));
bytes32 node4 = sha256(abi.encodePacked(bytes32(0), bytes32(0)));
bytes32 node12 = sha256(abi.encodePacked(node1, node2));
bytes32 node34 = sha256(abi.encodePacked(node3, node4));
return sha256(abi.encodePacked(node12, node34));
}
function _update_branch(bytes32 root) private {
uint256 size = deposit_count;
for (uint256 height = 0; height < DEPOSIT_CONTRACT_TREE_DEPTH; height++) {
if ((size & 1) == 1) {
branch[height] = root;
return;
}
root = sha256(abi.encodePacked(branch[height], root));
size /= 2;
}
// 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);
}
}
Compiler Settings
{"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":true},"metadata":{"bytecodeHash":"ipfs"},"libraries":{"DepositContract.sol":{}},"evmVersion":"london"}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"event","name":"DepositEvent","inputs":[{"type":"bytes","name":"pubkey","internalType":"bytes","indexed":false},{"type":"bytes","name":"withdrawal_credentials","internalType":"bytes","indexed":false},{"type":"bytes","name":"contract_address","internalType":"bytes","indexed":false},{"type":"bytes","name":"amount","internalType":"bytes","indexed":false},{"type":"bytes","name":"signature","internalType":"bytes","indexed":false},{"type":"bytes","name":"index","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"payable","outputs":[],"name":"deposit","inputs":[{"type":"bytes","name":"pubkey","internalType":"bytes"},{"type":"bytes","name":"withdrawal_credentials","internalType":"bytes"},{"type":"bytes","name":"contract_address","internalType":"bytes"},{"type":"bytes","name":"signature","internalType":"bytes"},{"type":"bytes32","name":"deposit_data_root","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"get_contract_owner","inputs":[{"type":"address","name":"contract_address","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes","name":"","internalType":"bytes"}],"name":"get_deposit_count","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"get_deposit_root","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"interfaceId","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transfer_contract_ownership","inputs":[{"type":"address","name":"contract_address","internalType":"address"},{"type":"address","name":"new_owner_address","internalType":"address"}]}]
Contract Creation Code
0x6080604052604180546001600160a01b0319167310000000000000000000000000000000000000021790553480156200003757600080fd5b5060005b62000049600160206200014a565b8110156200012d5760026021826020811062000069576200006962000166565b01546021836020811062000081576200008162000166565b015460408051602081019390935282015260600160408051601f1981840301815290829052620000b1916200017c565b602060405180830381855afa158015620000cf573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190620000f49190620001ad565b602162000103836001620001c7565b6020811062000116576200011662000166565b0155806200012481620001dd565b9150506200003b565b50620001f9565b634e487b7160e01b600052601160045260246000fd5b8181038181111562000160576200016062000134565b92915050565b634e487b7160e01b600052603260045260246000fd5b6000825160005b818110156200019f576020818601810151858301520162000183565b506000920191825250919050565b600060208284031215620001c057600080fd5b5051919050565b8082018082111562000160576200016062000134565b600060018201620001f257620001f262000134565b5060010190565b61193e80620002096000396000f3fe6080604052600436106100555760003560e01c806301ffc9a71461005a57806336a8d2301461008f578063621fd130146100b1578063847dbe4d146100d3578063c1da06e21461010b578063c5f2892f1461011e575b600080fd5b34801561006657600080fd5b5061007a6100753660046112ea565b610141565b60405190151581526020015b60405180910390f35b34801561009b57600080fd5b506100af6100aa366004611337565b610178565b005b3480156100bd57600080fd5b506100c6610310565b60405161008691906113ba565b3480156100df57600080fd5b506100f36100ee3660046113cd565b610322565b6040516001600160a01b039091168152602001610086565b6100af610119366004611431565b610459565b34801561012a57600080fd5b5061013361092b565b604051908152602001610086565b60006001600160e01b031982166301ffc9a760e01b148061017257506001600160e01b031982166301a9c46560e71b145b92915050565b6001600160a01b0382166000036101ef5760405162461bcd60e51b815260206004820152603060248201527f4465706f736974436f6e74726163743a20436f6e74726163742061646472657360448201526f1cc818d85b9b9bdd081899481b9d5b1b60821b60648201526084015b60405180910390fd5b6001600160a01b03811660000361025e5760405162461bcd60e51b815260206004820152602d60248201527f4465706f736974436f6e74726163743a204f776e65722061646472657373206360448201526c185b9b9bdd081899481b9d5b1b609a1b60648201526084016101e6565b61026782610322565b6001600160a01b0316336001600160a01b0316146102e25760405162461bcd60e51b815260206004820152603260248201527f4465706f736974436f6e74726163743a204f6e6c79206f776e65722063616e2060448201527107472616e73666572206f776e6572736869760741b60648201526084016101e6565b6001600160a01b03918216600090815260426020526040902080546001600160a01b03191691909216179055565b606061031d602054610aff565b905090565b6001600160a01b038082166000908152604260205260408120549091161561036357506001600160a01b039081166000908152604260205260409020541690565b6041546040516bffffffffffffffffffffffff19606085901b16602082015260009182916001600160a01b039091169060340160408051601f19818403018152908290526103b0916114fd565b600060405180830381855afa9150503d80600081146103eb576040519150601f19603f3d011682016040523d82523d6000602084013e6103f0565b606091505b50915091508161044e5760405162461bcd60e51b8152602060048201526024808201527f4465706f736974436f6e74726163743a2043616e6e6f7420676574206465706c60448201526337bcb2b960e11b60648201526084016101e6565b601401519392505050565b603088146104b85760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084016101e6565b602086146104d85760405162461bcd60e51b81526004016101e690611519565b601484146104f85760405162461bcd60e51b81526004016101e690611519565b6060821461055a5760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b60648201526084016101e6565b600061059b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cb392505050565b90506001600160a01b0381161561062857336105b682610322565b6001600160a01b0316146106285760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a2073656e6465722073686f756c64206260448201527219481bdddb995c881bd98818dbdb9d1c9858dd606a1b60648201526084016101e6565b680de0b6b3a7640000003410156106905760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b60648201526084016101e6565b61069e633b9aca0034611585565b156107075760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b60648201526084016101e6565b6000610717633b9aca00346115af565b905067ffffffffffffffff8111156107815760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b60648201526084016101e6565b600061078c82610aff565b90507f9690c6325860650852f0f0bd0e7d47145a3d0c2c5c92cba852bad61c02928b098c8c8c8c8c8c878d8d6107c3602054610aff565b6040516107d99a999897969594939291906115ec565b60405180910390a160006107f48d8d8d8d8d8d888e8e610cba565b90508481146108885760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a4016101e6565b60016108966020600261175a565b6108a09190611766565b602054106108fa5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b60648201526084016101e6565b60016020600082825461090d9190611779565b9091555061091c905081611202565b50505050505050505050505050565b6020546000908190815b6020811015610a7b57816001166001036109d55760026000826020811061095e5761095e61178c565b0154604080516020810192909252810185905260600160408051601f198184030181529082905261098e916114fd565b602060405180830381855afa1580156109ab573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109ce91906117a2565b9250610a5c565b600283602183602081106109eb576109eb61178c565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a19916114fd565b602060405180830381855afa158015610a36573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610a5991906117a2565b92505b610a676002836115af565b915080610a73816117bb565b915050610935565b50600282610a8a602054610aff565b604051610a9e9291906000906020016117d4565b60408051601f1981840301815290829052610ab8916114fd565b602060405180830381855afa158015610ad5573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610af891906117a2565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b82600081518110610b3f57610b3f61178c565b60200101906001600160f81b031916908160001a9053508060061a60f81b82600181518110610b7057610b7061178c565b60200101906001600160f81b031916908160001a9053508060051a60f81b82600281518110610ba157610ba161178c565b60200101906001600160f81b031916908160001a9053508060041a60f81b82600381518110610bd257610bd261178c565b60200101906001600160f81b031916908160001a9053508060031a60f81b82600481518110610c0357610c0361178c565b60200101906001600160f81b031916908160001a9053508060021a60f81b82600581518110610c3457610c3461178c565b60200101906001600160f81b031916908160001a9053508060011a60f81b82600681518110610c6557610c6561178c565b60200101906001600160f81b031916908160001a9053508060001a60f81b82600781518110610c9657610c9661178c565b60200101906001600160f81b031916908160001a90535050919050565b6014015190565b60008060028b8b600060801b604051602001610cd893929190611810565b60408051601f1981840301815290829052610cf2916114fd565b602060405180830381855afa158015610d0f573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610d3291906117a2565b90506000600280610d46604084888a611837565b604051602001610d57929190611861565b60408051601f1981840301815290829052610d71916114fd565b602060405180830381855afa158015610d8e573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610db191906117a2565b6002610dc0876040818b611837565b604051610dd4929190600090602001611871565b60408051601f1981840301815290829052610dee916114fd565b602060405180830381855afa158015610e0b573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610e2e91906117a2565b60408051602081019390935282015260600160408051601f1981840301815290829052610e5a916114fd565b602060405180830381855afa158015610e77573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610e9a91906117a2565b905060006002838c8c604051602001610eb593929190611883565b60408051601f1981840301815290829052610ecf916114fd565b602060405180830381855afa158015610eec573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610f0f91906117a2565b604051909150600090600290610f31908c908c9085908d90829060200161189d565b60408051601f1981840301815290829052610f4b916114fd565b602060405180830381855afa158015610f68573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610f8b91906117a2565b604080516020810186905260009181018290529192509060029060600160408051601f1981840301815290829052610fc2916114fd565b602060405180830381855afa158015610fdf573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061100291906117a2565b604080516000602082018190529181018290529192509060029060600160408051601f1981840301815290829052611039916114fd565b602060405180830381855afa158015611056573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061107991906117a2565b905060006002858560405160200161109b929190918252602082015260400190565b60408051601f19818403018152908290526110b5916114fd565b602060405180830381855afa1580156110d2573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906110f591906117a2565b9050600060028484604051602001611117929190918252602082015260400190565b60408051601f1981840301815290829052611131916114fd565b602060405180830381855afa15801561114e573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061117191906117a2565b905060028282604051602001611191929190918252602082015260400190565b60408051601f19818403018152908290526111ab916114fd565b602060405180830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906111eb91906117a2565b985050505050505050509998505050505050505050565b60205460005b60208110156112dd57816001166001036112375782600082602081106112305761123061178c565b0155505050565b60026000826020811061124c5761124c61178c565b0154604080516020810192909252810185905260600160408051601f198184030181529082905261127c916114fd565b602060405180830381855afa158015611299573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906112bc91906117a2565b92506112c96002836115af565b9150806112d5816117bb565b915050611208565b506112e66118f2565b5050565b6000602082840312156112fc57600080fd5b81356001600160e01b03198116811461131457600080fd5b9392505050565b80356001600160a01b038116811461133257600080fd5b919050565b6000806040838503121561134a57600080fd5b6113538361131b565b91506113616020840161131b565b90509250929050565b60005b8381101561138557818101518382015260200161136d565b50506000910152565b600081518084526113a681602086016020860161136a565b601f01601f19169290920160200192915050565b602081526000611314602083018461138e565b6000602082840312156113df57600080fd5b6113148261131b565b60008083601f8401126113fa57600080fd5b50813567ffffffffffffffff81111561141257600080fd5b60208301915083602082850101111561142a57600080fd5b9250929050565b600080600080600080600080600060a08a8c03121561144f57600080fd5b893567ffffffffffffffff8082111561146757600080fd5b6114738d838e016113e8565b909b50995060208c013591508082111561148c57600080fd5b6114988d838e016113e8565b909950975060408c01359150808211156114b157600080fd5b6114bd8d838e016113e8565b909750955060608c01359150808211156114d657600080fd5b506114e38c828d016113e8565b9a9d999c50979a9699959894979660800135949350505050565b6000825161150f81846020870161136a565b9190910192915050565b60208082526036908201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616040820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b6000826115945761159461156f565b500690565b634e487b7160e01b600052601160045260246000fd5b6000826115be576115be61156f565b500490565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60c08152600061160060c083018c8e6115c3565b8281036020840152611613818b8d6115c3565b9050828103604084015261162881898b6115c3565b9050828103606084015261163c818861138e565b905082810360808401526116518186886115c3565b905082810360a0840152611665818561138e565b9d9c50505050505050505050505050565b600181815b808511156116b157816000190482111561169757611697611599565b808516156116a457918102915b93841c939080029061167b565b509250929050565b6000826116c857506001610172565b816116d557506000610172565b81600181146116eb57600281146116f557611711565b6001915050610172565b60ff84111561170657611706611599565b50506001821b610172565b5060208310610133831016604e8410600b8410161715611734575081810a610172565b61173e8383611676565b806000190482111561175257611752611599565b029392505050565b600061131483836116b9565b8181038181111561017257610172611599565b8082018082111561017257610172611599565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156117b457600080fd5b5051919050565b6000600182016117cd576117cd611599565b5060010190565b838152600083516117ec81602085016020880161136a565b67ffffffffffffffff19939093169190920160208101919091526038019392505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b6000808585111561184757600080fd5b8386111561185457600080fd5b5050820193919092039150565b8183823760009101908152919050565b82848237909101908152602001919050565b838152818360208301376000910160200190815292915050565b8486823760008582016bffffffffffffffffffffffff60a01b8616815284516118cd81600c84016020890161136a565b67ffffffffffffffff19949094169301600c8101939093525050602401949350505050565b634e487b7160e01b600052600160045260246000fdfea264697066735822122052366f8a8c8d63af60f71e74b52b95a317eaf794d2f525ea4aa959fca93ccc0a64736f6c63430008100033
Deployed ByteCode
0x6080604052600436106100555760003560e01c806301ffc9a71461005a57806336a8d2301461008f578063621fd130146100b1578063847dbe4d146100d3578063c1da06e21461010b578063c5f2892f1461011e575b600080fd5b34801561006657600080fd5b5061007a6100753660046112ea565b610141565b60405190151581526020015b60405180910390f35b34801561009b57600080fd5b506100af6100aa366004611337565b610178565b005b3480156100bd57600080fd5b506100c6610310565b60405161008691906113ba565b3480156100df57600080fd5b506100f36100ee3660046113cd565b610322565b6040516001600160a01b039091168152602001610086565b6100af610119366004611431565b610459565b34801561012a57600080fd5b5061013361092b565b604051908152602001610086565b60006001600160e01b031982166301ffc9a760e01b148061017257506001600160e01b031982166301a9c46560e71b145b92915050565b6001600160a01b0382166000036101ef5760405162461bcd60e51b815260206004820152603060248201527f4465706f736974436f6e74726163743a20436f6e74726163742061646472657360448201526f1cc818d85b9b9bdd081899481b9d5b1b60821b60648201526084015b60405180910390fd5b6001600160a01b03811660000361025e5760405162461bcd60e51b815260206004820152602d60248201527f4465706f736974436f6e74726163743a204f776e65722061646472657373206360448201526c185b9b9bdd081899481b9d5b1b609a1b60648201526084016101e6565b61026782610322565b6001600160a01b0316336001600160a01b0316146102e25760405162461bcd60e51b815260206004820152603260248201527f4465706f736974436f6e74726163743a204f6e6c79206f776e65722063616e2060448201527107472616e73666572206f776e6572736869760741b60648201526084016101e6565b6001600160a01b03918216600090815260426020526040902080546001600160a01b03191691909216179055565b606061031d602054610aff565b905090565b6001600160a01b038082166000908152604260205260408120549091161561036357506001600160a01b039081166000908152604260205260409020541690565b6041546040516bffffffffffffffffffffffff19606085901b16602082015260009182916001600160a01b039091169060340160408051601f19818403018152908290526103b0916114fd565b600060405180830381855afa9150503d80600081146103eb576040519150601f19603f3d011682016040523d82523d6000602084013e6103f0565b606091505b50915091508161044e5760405162461bcd60e51b8152602060048201526024808201527f4465706f736974436f6e74726163743a2043616e6e6f7420676574206465706c60448201526337bcb2b960e11b60648201526084016101e6565b601401519392505050565b603088146104b85760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a20696e76616c6964207075626b6579206044820152650d8cadccee8d60d31b60648201526084016101e6565b602086146104d85760405162461bcd60e51b81526004016101e690611519565b601484146104f85760405162461bcd60e51b81526004016101e690611519565b6060821461055a5760405162461bcd60e51b815260206004820152602960248201527f4465706f736974436f6e74726163743a20696e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b60648201526084016101e6565b600061059b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cb392505050565b90506001600160a01b0381161561062857336105b682610322565b6001600160a01b0316146106285760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a2073656e6465722073686f756c64206260448201527219481bdddb995c881bd98818dbdb9d1c9858dd606a1b60648201526084016101e6565b680de0b6b3a7640000003410156106905760405162461bcd60e51b815260206004820152602660248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152656f6f206c6f7760d01b60648201526084016101e6565b61069e633b9aca0034611585565b156107075760405162461bcd60e51b815260206004820152603360248201527f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e6044820152726f74206d756c7469706c65206f66206777656960681b60648201526084016101e6565b6000610717633b9aca00346115af565b905067ffffffffffffffff8111156107815760405162461bcd60e51b815260206004820152602760248201527f4465706f736974436f6e74726163743a206465706f7369742076616c756520746044820152660dede40d0d2ced60cb1b60648201526084016101e6565b600061078c82610aff565b90507f9690c6325860650852f0f0bd0e7d47145a3d0c2c5c92cba852bad61c02928b098c8c8c8c8c8c878d8d6107c3602054610aff565b6040516107d99a999897969594939291906115ec565b60405180910390a160006107f48d8d8d8d8d8d888e8e610cba565b90508481146108885760405162461bcd60e51b815260206004820152605460248201527f4465706f736974436f6e74726163743a207265636f6e7374727563746564204460448201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960648201527319590819195c1bdcda5d17d9185d1857dc9bdbdd60621b608482015260a4016101e6565b60016108966020600261175a565b6108a09190611766565b602054106108fa5760405162461bcd60e51b815260206004820152602160248201527f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6044820152601b60fa1b60648201526084016101e6565b60016020600082825461090d9190611779565b9091555061091c905081611202565b50505050505050505050505050565b6020546000908190815b6020811015610a7b57816001166001036109d55760026000826020811061095e5761095e61178c565b0154604080516020810192909252810185905260600160408051601f198184030181529082905261098e916114fd565b602060405180830381855afa1580156109ab573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906109ce91906117a2565b9250610a5c565b600283602183602081106109eb576109eb61178c565b015460408051602081019390935282015260600160408051601f1981840301815290829052610a19916114fd565b602060405180830381855afa158015610a36573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610a5991906117a2565b92505b610a676002836115af565b915080610a73816117bb565b915050610935565b50600282610a8a602054610aff565b604051610a9e9291906000906020016117d4565b60408051601f1981840301815290829052610ab8916114fd565b602060405180830381855afa158015610ad5573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610af891906117a2565b9250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b82600081518110610b3f57610b3f61178c565b60200101906001600160f81b031916908160001a9053508060061a60f81b82600181518110610b7057610b7061178c565b60200101906001600160f81b031916908160001a9053508060051a60f81b82600281518110610ba157610ba161178c565b60200101906001600160f81b031916908160001a9053508060041a60f81b82600381518110610bd257610bd261178c565b60200101906001600160f81b031916908160001a9053508060031a60f81b82600481518110610c0357610c0361178c565b60200101906001600160f81b031916908160001a9053508060021a60f81b82600581518110610c3457610c3461178c565b60200101906001600160f81b031916908160001a9053508060011a60f81b82600681518110610c6557610c6561178c565b60200101906001600160f81b031916908160001a9053508060001a60f81b82600781518110610c9657610c9661178c565b60200101906001600160f81b031916908160001a90535050919050565b6014015190565b60008060028b8b600060801b604051602001610cd893929190611810565b60408051601f1981840301815290829052610cf2916114fd565b602060405180830381855afa158015610d0f573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610d3291906117a2565b90506000600280610d46604084888a611837565b604051602001610d57929190611861565b60408051601f1981840301815290829052610d71916114fd565b602060405180830381855afa158015610d8e573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610db191906117a2565b6002610dc0876040818b611837565b604051610dd4929190600090602001611871565b60408051601f1981840301815290829052610dee916114fd565b602060405180830381855afa158015610e0b573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610e2e91906117a2565b60408051602081019390935282015260600160408051601f1981840301815290829052610e5a916114fd565b602060405180830381855afa158015610e77573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610e9a91906117a2565b905060006002838c8c604051602001610eb593929190611883565b60408051601f1981840301815290829052610ecf916114fd565b602060405180830381855afa158015610eec573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610f0f91906117a2565b604051909150600090600290610f31908c908c9085908d90829060200161189d565b60408051601f1981840301815290829052610f4b916114fd565b602060405180830381855afa158015610f68573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190610f8b91906117a2565b604080516020810186905260009181018290529192509060029060600160408051601f1981840301815290829052610fc2916114fd565b602060405180830381855afa158015610fdf573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061100291906117a2565b604080516000602082018190529181018290529192509060029060600160408051601f1981840301815290829052611039916114fd565b602060405180830381855afa158015611056573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061107991906117a2565b905060006002858560405160200161109b929190918252602082015260400190565b60408051601f19818403018152908290526110b5916114fd565b602060405180830381855afa1580156110d2573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906110f591906117a2565b9050600060028484604051602001611117929190918252602082015260400190565b60408051601f1981840301815290829052611131916114fd565b602060405180830381855afa15801561114e573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061117191906117a2565b905060028282604051602001611191929190918252602082015260400190565b60408051601f19818403018152908290526111ab916114fd565b602060405180830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906111eb91906117a2565b985050505050505050509998505050505050505050565b60205460005b60208110156112dd57816001166001036112375782600082602081106112305761123061178c565b0155505050565b60026000826020811061124c5761124c61178c565b0154604080516020810192909252810185905260600160408051601f198184030181529082905261127c916114fd565b602060405180830381855afa158015611299573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906112bc91906117a2565b92506112c96002836115af565b9150806112d5816117bb565b915050611208565b506112e66118f2565b5050565b6000602082840312156112fc57600080fd5b81356001600160e01b03198116811461131457600080fd5b9392505050565b80356001600160a01b038116811461133257600080fd5b919050565b6000806040838503121561134a57600080fd5b6113538361131b565b91506113616020840161131b565b90509250929050565b60005b8381101561138557818101518382015260200161136d565b50506000910152565b600081518084526113a681602086016020860161136a565b601f01601f19169290920160200192915050565b602081526000611314602083018461138e565b6000602082840312156113df57600080fd5b6113148261131b565b60008083601f8401126113fa57600080fd5b50813567ffffffffffffffff81111561141257600080fd5b60208301915083602082850101111561142a57600080fd5b9250929050565b600080600080600080600080600060a08a8c03121561144f57600080fd5b893567ffffffffffffffff8082111561146757600080fd5b6114738d838e016113e8565b909b50995060208c013591508082111561148c57600080fd5b6114988d838e016113e8565b909950975060408c01359150808211156114b157600080fd5b6114bd8d838e016113e8565b909750955060608c01359150808211156114d657600080fd5b506114e38c828d016113e8565b9a9d999c50979a9699959894979660800135949350505050565b6000825161150f81846020870161136a565b9190910192915050565b60208082526036908201527f4465706f736974436f6e74726163743a20696e76616c696420776974686472616040820152750eec2d8bec6e4cac8cadce8d2c2d8e640d8cadccee8d60531b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b6000826115945761159461156f565b500690565b634e487b7160e01b600052601160045260246000fd5b6000826115be576115be61156f565b500490565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60c08152600061160060c083018c8e6115c3565b8281036020840152611613818b8d6115c3565b9050828103604084015261162881898b6115c3565b9050828103606084015261163c818861138e565b905082810360808401526116518186886115c3565b905082810360a0840152611665818561138e565b9d9c50505050505050505050505050565b600181815b808511156116b157816000190482111561169757611697611599565b808516156116a457918102915b93841c939080029061167b565b509250929050565b6000826116c857506001610172565b816116d557506000610172565b81600181146116eb57600281146116f557611711565b6001915050610172565b60ff84111561170657611706611599565b50506001821b610172565b5060208310610133831016604e8410600b8410161715611734575081810a610172565b61173e8383611676565b806000190482111561175257611752611599565b029392505050565b600061131483836116b9565b8181038181111561017257610172611599565b8082018082111561017257610172611599565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156117b457600080fd5b5051919050565b6000600182016117cd576117cd611599565b5060010190565b838152600083516117ec81602085016020880161136a565b67ffffffffffffffff19939093169190920160208101919091526038019392505050565b828482376fffffffffffffffffffffffffffffffff19919091169101908152601001919050565b6000808585111561184757600080fd5b8386111561185457600080fd5b5050820193919092039150565b8183823760009101908152919050565b82848237909101908152602001919050565b838152818360208301376000910160200190815292915050565b8486823760008582016bffffffffffffffffffffffff60a01b8616815284516118cd81600c84016020890161136a565b67ffffffffffffffff19949094169301600c8101939093525050602401949350505050565b634e487b7160e01b600052600160045260246000fdfea264697066735822122052366f8a8c8d63af60f71e74b52b95a317eaf794d2f525ea4aa959fca93ccc0a64736f6c63430008100033