Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- TestingContract4
- Optimization enabled
- true
- Compiler version
- v0.8.22+commit.4fc1097e
- Optimization runs
- 200
- EVM Version
- paris
- Verified at
- 2025-05-30T10:49:33.554136Z
Constructor Arguments
0x000000000000000000000000000000000000000000000000000009184e72a000000000000000000000000000000000000000000000000000000000003b9aca00
Arg [0] (<b>uint256</b>) : 10000000000000 Arg [1] (<b>uint256</b>) : 1000000000
Contract source code
// File: @openzeppelin/contracts/security/ReentrancyGuard.sol // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } } // File: staking.sol // File: bitqube/validatorstaking.sol pragma solidity ^0.8.22; contract TestingContract4 is ReentrancyGuard{ // State variables address public owner; address public distributor; uint256 public stakeAmount; uint256 public dailyReward; uint256 public constant rewardCycleStartTimestamp = 1735561698; // Hardcoded reward cycle start timestamp uint256 public lastRewardTime; uint256 public validatorCount; uint256 public constant rewardCycleDuration = 1 minutes; mapping(address => uint256) public joinTimestamp; mapping(address => uint256) public unclaimedRewards; mapping(address => bool) public isValidator; address[] public validators; // Events event Stake(address indexed validator, uint256 timestamp); event Unstake(address indexed validator, uint256 timestamp); event RewardsDistributed(address indexed distributor, uint256 totalRewards); event RewardsClaimed(address indexed validator, uint256 amount); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event FundsWithdrawn(address indexed owner, uint256 amount); event FundsAdded(address indexed sender, uint256 amount); // Modifiers modifier onlyOwner() { require(msg.sender == owner, "Caller is not the owner"); _; } modifier onlyDistributorOrOwner() { require(msg.sender == distributor || msg.sender == owner, "Caller is not authorized"); _; } modifier onlyValidator() { require(isValidator[msg.sender], "Caller is not a validator"); _; } // Constructor constructor(uint256 _stakeAmount, uint256 _dailyReward) { owner = msg.sender; stakeAmount = _stakeAmount; dailyReward = _dailyReward; lastRewardTime = rewardCycleStartTimestamp; } // Functions function setStakeAmount(uint256 _stakeAmount) external onlyOwner nonReentrant{ stakeAmount = _stakeAmount; } function setDailyReward(uint256 _dailyReward) external onlyOwner nonReentrant{ dailyReward = _dailyReward; } function setDistributor(address _distributor) external onlyOwner nonReentrant{ distributor = _distributor; } function transferOwnership(address newOwner) external onlyOwner nonReentrant{ require(newOwner != address(0), "New owner is the zero address"); emit OwnershipTransferred(owner, newOwner); owner = newOwner; } function stake() external payable nonReentrant{ require(!isValidator[msg.sender], "Already a validator"); require(msg.value == stakeAmount, "Incorrect stake amount"); isValidator[msg.sender] = true; joinTimestamp[msg.sender] = block.timestamp; unclaimedRewards[msg.sender] = 0; validators.push(msg.sender); validatorCount++; emit Stake(msg.sender, block.timestamp); } function unstake() external onlyValidator nonReentrant{ uint256 index = _findValidatorIndex(msg.sender); require(index < validators.length, "Validator not found"); // Remove validator validators[index] = validators[validators.length - 1]; validators.pop(); isValidator[msg.sender] = false; joinTimestamp[msg.sender] = 0; validatorCount--; // Refund stake amount payable(msg.sender).transfer(stakeAmount); emit Unstake(msg.sender, block.timestamp); } function distributeRewards() external onlyDistributorOrOwner nonReentrant{ require(block.timestamp >= lastRewardTime + rewardCycleDuration, "Reward cycle not complete"); uint256 timeElapsed = block.timestamp - lastRewardTime; uint256 totalReward = (timeElapsed / rewardCycleDuration) * dailyReward; if (validatorCount >= 3) { uint256 rewardPerValidator = totalReward / validatorCount; for (uint256 i = 0; i < validators.length; i++) { unclaimedRewards[validators[i]] += rewardPerValidator; } } else { for (uint256 i = 0; i < validators.length; i++) { unclaimedRewards[validators[i]] += dailyReward; } } lastRewardTime = block.timestamp; emit RewardsDistributed(msg.sender, totalReward); } function claimRewards() external onlyValidator nonReentrant{ uint256 rewards = unclaimedRewards[msg.sender]; require(rewards > 0, "No rewards to claim"); unclaimedRewards[msg.sender] = 0; payable(msg.sender).transfer(rewards); emit RewardsClaimed(msg.sender, rewards); } function addFunds() external payable nonReentrant{ require(msg.value > 0, "Must send some funds"); emit FundsAdded(msg.sender, msg.value); } function withdrawExcessFunds(uint256 amount) external onlyOwner nonReentrant{ uint256 contractBalance = address(this).balance; uint256 lockedFunds = stakeAmount * validatorCount; require(amount <= contractBalance - lockedFunds, "Insufficient excess funds"); payable(owner).transfer(amount); emit FundsWithdrawn(owner, amount); } function getValidatorCount() external view returns (uint256) { return validatorCount; } // Internal utility functions function _findValidatorIndex(address validator) internal view returns (uint256) { for (uint256 i = 0; i < validators.length; i++) { if (validators[i] == validator) { return i; } } revert("Validator not found"); } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"uint256","name":"_stakeAmount","internalType":"uint256"},{"type":"uint256","name":"_dailyReward","internalType":"uint256"}]},{"type":"event","name":"FundsAdded","inputs":[{"type":"address","name":"sender","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"FundsWithdrawn","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RewardsClaimed","inputs":[{"type":"address","name":"validator","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"RewardsDistributed","inputs":[{"type":"address","name":"distributor","internalType":"address","indexed":true},{"type":"uint256","name":"totalRewards","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Stake","inputs":[{"type":"address","name":"validator","internalType":"address","indexed":true},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Unstake","inputs":[{"type":"address","name":"validator","internalType":"address","indexed":true},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"payable","outputs":[],"name":"addFunds","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimRewards","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"dailyReward","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"distributeRewards","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"distributor","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getValidatorCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isValidator","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"joinTimestamp","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastRewardTime","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardCycleDuration","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardCycleStartTimestamp","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDailyReward","inputs":[{"type":"uint256","name":"_dailyReward","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDistributor","inputs":[{"type":"address","name":"_distributor","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setStakeAmount","inputs":[{"type":"uint256","name":"_stakeAmount","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"stake","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"stakeAmount","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"unclaimedRewards","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unstake","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"validatorCount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"validators","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawExcessFunds","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]}]
Contract Creation Code
0x608060405234801561001057600080fd5b5060405161117338038061117383398101604081905261002f9161005c565b6001600081905580546001600160a01b0319163317905560039190915560045563677291e2600555610080565b6000806040838503121561006f57600080fd5b505080516020909101519092909150565b6110e48061008f6000396000f3fe6080604052600436106101405760003560e01c806375619ab5116100b6578063bfe109281161006f578063bfe1092814610312578063c964ad4514610332578063f2fde38b14610348578063f3cbe29314610368578063f833735c14610388578063facd743b146103b557600080fd5b806375619ab51461026f5780638da5cb5b1461028f5780639231cf74146102af578063949813b8146102c557806396e8e95c146102f2578063a26759cb1461030a57600080fd5b80633a4b66f1116101085780633a4b66f1146101f25780633fa758e9146101fa57806343808c501461020f57806360c7dc471461022f5780636f4a2cd0146102455780637071688a1461025a57600080fd5b80630aa43533146101455780630f43a677146101675780632def66201461019057806335aa2e44146101a5578063372500ab146101dd575b600080fd5b34801561015157600080fd5b50610165610160366004610f57565b6103f5565b005b34801561017357600080fd5b5061017d60065481565b6040519081526020015b60405180910390f35b34801561019c57600080fd5b50610165610442565b3480156101b157600080fd5b506101c56101c0366004610f57565b61064e565b6040516001600160a01b039091168152602001610187565b3480156101e957600080fd5b50610165610678565b61016561079c565b34801561020657600080fd5b5061017d603c81565b34801561021b57600080fd5b5061016561022a366004610f57565b61090a565b34801561023b57600080fd5b5061017d60035481565b34801561025157600080fd5b5061016561094b565b34801561026657600080fd5b5060065461017d565b34801561027b57600080fd5b5061016561028a366004610f70565b610b88565b34801561029b57600080fd5b506001546101c5906001600160a01b031681565b3480156102bb57600080fd5b5061017d60055481565b3480156102d157600080fd5b5061017d6102e0366004610f70565b60086020526000908152604090205481565b3480156102fe57600080fd5b5061017d63677291e281565b610165610bdd565b34801561031e57600080fd5b506002546101c5906001600160a01b031681565b34801561033e57600080fd5b5061017d60045481565b34801561035457600080fd5b50610165610363366004610f70565b610c5e565b34801561037457600080fd5b50610165610383366004610f57565b610d41565b34801561039457600080fd5b5061017d6103a3366004610f70565b60076020526000908152604090205481565b3480156103c157600080fd5b506103e56103d0366004610f70565b60096020526000908152604090205460ff1681565b6040519015158152602001610187565b6001546001600160a01b031633146104285760405162461bcd60e51b815260040161041f90610fa0565b60405180910390fd5b610430610e6c565b600481905561043f6001600055565b50565b3360009081526009602052604090205460ff1661049d5760405162461bcd60e51b815260206004820152601960248201527821b0b63632b91034b9903737ba1030903b30b634b230ba37b960391b604482015260640161041f565b6104a5610e6c565b60006104b033610ec5565b600a5490915081106104fa5760405162461bcd60e51b815260206004820152601360248201527215985b1a59185d1bdc881b9bdd08199bdd5b99606a1b604482015260640161041f565b600a805461050a90600190610fed565b8154811061051a5761051a611006565b600091825260209091200154600a80546001600160a01b03909216918390811061054657610546611006565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600a8054806105855761058561101c565b60008281526020808220830160001990810180546001600160a01b0319169055909201909255338252600981526040808320805460ff191690556007909152812081905560068054916105d783611032565b9091555050600354604051339180156108fc02916000818181858888f1935050505015801561060a573d6000803e3d6000fd5b5060405142815233907f85082129d87b2fe11527cb1b3b7a520aeb5aa6913f88a3d8757fe40d1db02fdd906020015b60405180910390a25061064c6001600055565b565b600a818154811061065e57600080fd5b6000918252602090912001546001600160a01b0316905081565b3360009081526009602052604090205460ff166106d35760405162461bcd60e51b815260206004820152601960248201527821b0b63632b91034b9903737ba1030903b30b634b230ba37b960391b604482015260640161041f565b6106db610e6c565b336000908152600860205260409020548061072e5760405162461bcd60e51b81526020600482015260136024820152724e6f207265776172647320746f20636c61696d60681b604482015260640161041f565b336000818152600860205260408082208290555183156108fc0291849190818181858888f19350505050158015610769573d6000803e3d6000fd5b5060405181815233907ffc30cddea38e2bf4d6ea7d3f9ed3b6ad7f176419f4963bd81318067a4aee73fe90602001610639565b6107a4610e6c565b3360009081526009602052604090205460ff16156107fa5760405162461bcd60e51b815260206004820152601360248201527220b63932b0b23c9030903b30b634b230ba37b960691b604482015260640161041f565b60035434146108445760405162461bcd60e51b8152602060048201526016602482015275125b98dbdc9c9958dd081cdd185ad948185b5bdd5b9d60521b604482015260640161041f565b336000818152600960209081526040808320805460ff191660019081179091556007835281842042905560089092528220829055600a8054918201815582527fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80180546001600160a01b03191690921790915560068054916108c583611049565b909155505060405142815233907febedb8b3c678666e7f36970bc8f57abf6d8fa2e828c0da91ea5b75bf68ed101a906020015b60405180910390a261064c6001600055565b6001546001600160a01b031633146109345760405162461bcd60e51b815260040161041f90610fa0565b61093c610e6c565b600381905561043f6001600055565b6002546001600160a01b031633148061096e57506001546001600160a01b031633145b6109ba5760405162461bcd60e51b815260206004820152601860248201527f43616c6c6572206973206e6f7420617574686f72697a65640000000000000000604482015260640161041f565b6109c2610e6c565b603c6005546109d19190611062565b421015610a205760405162461bcd60e51b815260206004820152601960248201527f526577617264206379636c65206e6f7420636f6d706c65746500000000000000604482015260640161041f565b600060055442610a309190610fed565b90506000600454603c83610a449190611075565b610a4e9190611097565b9050600360065410610ad957600060065482610a6a9190611075565b905060005b600a54811015610ad2578160086000600a8481548110610a9157610a91611006565b60009182526020808320909101546001600160a01b0316835282019290925260400181208054909190610ac5908490611062565b9091555050600101610a6f565b5050610b43565b60005b600a54811015610b415760045460086000600a8481548110610b0057610b00611006565b60009182526020808320909101546001600160a01b0316835282019290925260400181208054909190610b34908490611062565b9091555050600101610adc565b505b4260055560405181815233907fdf29796aad820e4bb192f3a8d631b76519bcd2cbe77cc85af20e9df53cece0869060200160405180910390a2505061064c6001600055565b6001546001600160a01b03163314610bb25760405162461bcd60e51b815260040161041f90610fa0565b610bba610e6c565b600280546001600160a01b0319166001600160a01b038316179055600160005550565b610be5610e6c565b60003411610c2c5760405162461bcd60e51b81526020600482015260146024820152734d7573742073656e6420736f6d652066756e647360601b604482015260640161041f565b60405134815233907f8fe10ae416f22f5e5220b0018a6c1d4ff534d6aa3a471f2a20cb7747fe63e5b9906020016108f8565b6001546001600160a01b03163314610c885760405162461bcd60e51b815260040161041f90610fa0565b610c90610e6c565b6001600160a01b038116610ce65760405162461bcd60e51b815260206004820152601d60248201527f4e6577206f776e657220697320746865207a65726f2061646472657373000000604482015260640161041f565b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b03831617815560005550565b6001546001600160a01b03163314610d6b5760405162461bcd60e51b815260040161041f90610fa0565b610d73610e6c565b6006546003544791600091610d889190611097565b9050610d948183610fed565b831115610de35760405162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e74206578636573732066756e647300000000000000604482015260640161041f565b6001546040516001600160a01b039091169084156108fc029085906000818181858888f19350505050158015610e1d573d6000803e3d6000fd5b506001546040518481526001600160a01b03909116907feaff4b37086828766ad3268786972c0cd24259d4c87a80f9d3963a3c3d999b0d9060200160405180910390a2505061043f6001600055565b600260005403610ebe5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161041f565b6002600055565b6000805b600a54811015610f1857826001600160a01b0316600a8281548110610ef057610ef0611006565b6000918252602090912001546001600160a01b031603610f105792915050565b600101610ec9565b5060405162461bcd60e51b815260206004820152601360248201527215985b1a59185d1bdc881b9bdd08199bdd5b99606a1b604482015260640161041f565b600060208284031215610f6957600080fd5b5035919050565b600060208284031215610f8257600080fd5b81356001600160a01b0381168114610f9957600080fd5b9392505050565b60208082526017908201527f43616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561100057611000610fd7565b92915050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60008161104157611041610fd7565b506000190190565b60006001820161105b5761105b610fd7565b5060010190565b8082018082111561100057611000610fd7565b60008261109257634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761100057611000610fd756fea2646970667358221220aa71e0b9afd001f1661236c72a7519f9d91a9727253be37387201803cd146f0b64736f6c63430008160033000000000000000000000000000000000000000000000000000009184e72a000000000000000000000000000000000000000000000000000000000003b9aca00
Deployed ByteCode
0x6080604052600436106101405760003560e01c806375619ab5116100b6578063bfe109281161006f578063bfe1092814610312578063c964ad4514610332578063f2fde38b14610348578063f3cbe29314610368578063f833735c14610388578063facd743b146103b557600080fd5b806375619ab51461026f5780638da5cb5b1461028f5780639231cf74146102af578063949813b8146102c557806396e8e95c146102f2578063a26759cb1461030a57600080fd5b80633a4b66f1116101085780633a4b66f1146101f25780633fa758e9146101fa57806343808c501461020f57806360c7dc471461022f5780636f4a2cd0146102455780637071688a1461025a57600080fd5b80630aa43533146101455780630f43a677146101675780632def66201461019057806335aa2e44146101a5578063372500ab146101dd575b600080fd5b34801561015157600080fd5b50610165610160366004610f57565b6103f5565b005b34801561017357600080fd5b5061017d60065481565b6040519081526020015b60405180910390f35b34801561019c57600080fd5b50610165610442565b3480156101b157600080fd5b506101c56101c0366004610f57565b61064e565b6040516001600160a01b039091168152602001610187565b3480156101e957600080fd5b50610165610678565b61016561079c565b34801561020657600080fd5b5061017d603c81565b34801561021b57600080fd5b5061016561022a366004610f57565b61090a565b34801561023b57600080fd5b5061017d60035481565b34801561025157600080fd5b5061016561094b565b34801561026657600080fd5b5060065461017d565b34801561027b57600080fd5b5061016561028a366004610f70565b610b88565b34801561029b57600080fd5b506001546101c5906001600160a01b031681565b3480156102bb57600080fd5b5061017d60055481565b3480156102d157600080fd5b5061017d6102e0366004610f70565b60086020526000908152604090205481565b3480156102fe57600080fd5b5061017d63677291e281565b610165610bdd565b34801561031e57600080fd5b506002546101c5906001600160a01b031681565b34801561033e57600080fd5b5061017d60045481565b34801561035457600080fd5b50610165610363366004610f70565b610c5e565b34801561037457600080fd5b50610165610383366004610f57565b610d41565b34801561039457600080fd5b5061017d6103a3366004610f70565b60076020526000908152604090205481565b3480156103c157600080fd5b506103e56103d0366004610f70565b60096020526000908152604090205460ff1681565b6040519015158152602001610187565b6001546001600160a01b031633146104285760405162461bcd60e51b815260040161041f90610fa0565b60405180910390fd5b610430610e6c565b600481905561043f6001600055565b50565b3360009081526009602052604090205460ff1661049d5760405162461bcd60e51b815260206004820152601960248201527821b0b63632b91034b9903737ba1030903b30b634b230ba37b960391b604482015260640161041f565b6104a5610e6c565b60006104b033610ec5565b600a5490915081106104fa5760405162461bcd60e51b815260206004820152601360248201527215985b1a59185d1bdc881b9bdd08199bdd5b99606a1b604482015260640161041f565b600a805461050a90600190610fed565b8154811061051a5761051a611006565b600091825260209091200154600a80546001600160a01b03909216918390811061054657610546611006565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600a8054806105855761058561101c565b60008281526020808220830160001990810180546001600160a01b0319169055909201909255338252600981526040808320805460ff191690556007909152812081905560068054916105d783611032565b9091555050600354604051339180156108fc02916000818181858888f1935050505015801561060a573d6000803e3d6000fd5b5060405142815233907f85082129d87b2fe11527cb1b3b7a520aeb5aa6913f88a3d8757fe40d1db02fdd906020015b60405180910390a25061064c6001600055565b565b600a818154811061065e57600080fd5b6000918252602090912001546001600160a01b0316905081565b3360009081526009602052604090205460ff166106d35760405162461bcd60e51b815260206004820152601960248201527821b0b63632b91034b9903737ba1030903b30b634b230ba37b960391b604482015260640161041f565b6106db610e6c565b336000908152600860205260409020548061072e5760405162461bcd60e51b81526020600482015260136024820152724e6f207265776172647320746f20636c61696d60681b604482015260640161041f565b336000818152600860205260408082208290555183156108fc0291849190818181858888f19350505050158015610769573d6000803e3d6000fd5b5060405181815233907ffc30cddea38e2bf4d6ea7d3f9ed3b6ad7f176419f4963bd81318067a4aee73fe90602001610639565b6107a4610e6c565b3360009081526009602052604090205460ff16156107fa5760405162461bcd60e51b815260206004820152601360248201527220b63932b0b23c9030903b30b634b230ba37b960691b604482015260640161041f565b60035434146108445760405162461bcd60e51b8152602060048201526016602482015275125b98dbdc9c9958dd081cdd185ad948185b5bdd5b9d60521b604482015260640161041f565b336000818152600960209081526040808320805460ff191660019081179091556007835281842042905560089092528220829055600a8054918201815582527fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80180546001600160a01b03191690921790915560068054916108c583611049565b909155505060405142815233907febedb8b3c678666e7f36970bc8f57abf6d8fa2e828c0da91ea5b75bf68ed101a906020015b60405180910390a261064c6001600055565b6001546001600160a01b031633146109345760405162461bcd60e51b815260040161041f90610fa0565b61093c610e6c565b600381905561043f6001600055565b6002546001600160a01b031633148061096e57506001546001600160a01b031633145b6109ba5760405162461bcd60e51b815260206004820152601860248201527f43616c6c6572206973206e6f7420617574686f72697a65640000000000000000604482015260640161041f565b6109c2610e6c565b603c6005546109d19190611062565b421015610a205760405162461bcd60e51b815260206004820152601960248201527f526577617264206379636c65206e6f7420636f6d706c65746500000000000000604482015260640161041f565b600060055442610a309190610fed565b90506000600454603c83610a449190611075565b610a4e9190611097565b9050600360065410610ad957600060065482610a6a9190611075565b905060005b600a54811015610ad2578160086000600a8481548110610a9157610a91611006565b60009182526020808320909101546001600160a01b0316835282019290925260400181208054909190610ac5908490611062565b9091555050600101610a6f565b5050610b43565b60005b600a54811015610b415760045460086000600a8481548110610b0057610b00611006565b60009182526020808320909101546001600160a01b0316835282019290925260400181208054909190610b34908490611062565b9091555050600101610adc565b505b4260055560405181815233907fdf29796aad820e4bb192f3a8d631b76519bcd2cbe77cc85af20e9df53cece0869060200160405180910390a2505061064c6001600055565b6001546001600160a01b03163314610bb25760405162461bcd60e51b815260040161041f90610fa0565b610bba610e6c565b600280546001600160a01b0319166001600160a01b038316179055600160005550565b610be5610e6c565b60003411610c2c5760405162461bcd60e51b81526020600482015260146024820152734d7573742073656e6420736f6d652066756e647360601b604482015260640161041f565b60405134815233907f8fe10ae416f22f5e5220b0018a6c1d4ff534d6aa3a471f2a20cb7747fe63e5b9906020016108f8565b6001546001600160a01b03163314610c885760405162461bcd60e51b815260040161041f90610fa0565b610c90610e6c565b6001600160a01b038116610ce65760405162461bcd60e51b815260206004820152601d60248201527f4e6577206f776e657220697320746865207a65726f2061646472657373000000604482015260640161041f565b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b03831617815560005550565b6001546001600160a01b03163314610d6b5760405162461bcd60e51b815260040161041f90610fa0565b610d73610e6c565b6006546003544791600091610d889190611097565b9050610d948183610fed565b831115610de35760405162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e74206578636573732066756e647300000000000000604482015260640161041f565b6001546040516001600160a01b039091169084156108fc029085906000818181858888f19350505050158015610e1d573d6000803e3d6000fd5b506001546040518481526001600160a01b03909116907feaff4b37086828766ad3268786972c0cd24259d4c87a80f9d3963a3c3d999b0d9060200160405180910390a2505061043f6001600055565b600260005403610ebe5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161041f565b6002600055565b6000805b600a54811015610f1857826001600160a01b0316600a8281548110610ef057610ef0611006565b6000918252602090912001546001600160a01b031603610f105792915050565b600101610ec9565b5060405162461bcd60e51b815260206004820152601360248201527215985b1a59185d1bdc881b9bdd08199bdd5b99606a1b604482015260640161041f565b600060208284031215610f6957600080fd5b5035919050565b600060208284031215610f8257600080fd5b81356001600160a01b0381168114610f9957600080fd5b9392505050565b60208082526017908201527f43616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561100057611000610fd7565b92915050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b60008161104157611041610fd7565b506000190190565b60006001820161105b5761105b610fd7565b5060010190565b8082018082111561100057611000610fd7565b60008261109257634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761100057611000610fd756fea2646970667358221220aa71e0b9afd001f1661236c72a7519f9d91a9727253be37387201803cd146f0b64736f6c63430008160033