Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 311 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Claim Rewards | 18906387 | 405 days ago | IN | 0 ETH | 0.01841174 | ||||
Claim Rewards | 18133019 | 514 days ago | IN | 0 ETH | 0.00867702 | ||||
Claim Rewards | 18119101 | 516 days ago | IN | 0 ETH | 0.00615127 | ||||
Claim Rewards | 18104892 | 518 days ago | IN | 0 ETH | 0.0079238 | ||||
Claim Rewards | 18051763 | 525 days ago | IN | 0 ETH | 0.00930094 | ||||
Claim Rewards | 18046768 | 526 days ago | IN | 0 ETH | 0.00674942 | ||||
Claim Rewards | 18031951 | 528 days ago | IN | 0 ETH | 0.00622534 | ||||
Claim Rewards | 18024788 | 529 days ago | IN | 0 ETH | 0.00803545 | ||||
Claim Rewards | 18022679 | 529 days ago | IN | 0 ETH | 0.03702715 | ||||
Claim Rewards | 18018489 | 530 days ago | IN | 0 ETH | 0.00811322 | ||||
Claim Rewards | 18010164 | 531 days ago | IN | 0 ETH | 0.01026778 | ||||
Claim Rewards | 18007215 | 531 days ago | IN | 0 ETH | 0.01113316 | ||||
Claim Rewards | 18007106 | 531 days ago | IN | 0 ETH | 0.00991299 | ||||
Claim Rewards | 18006978 | 531 days ago | IN | 0 ETH | 0.00823633 | ||||
Claim Rewards | 18003454 | 532 days ago | IN | 0 ETH | 0.00764976 | ||||
Claim Rewards | 18003437 | 532 days ago | IN | 0 ETH | 0.00647213 | ||||
Claim Rewards | 18002068 | 532 days ago | IN | 0 ETH | 0.00610411 | ||||
Claim Rewards | 18002064 | 532 days ago | IN | 0 ETH | 0.00548248 | ||||
Claim Rewards | 18001905 | 532 days ago | IN | 0 ETH | 0.00547683 | ||||
Claim Rewards | 17992758 | 533 days ago | IN | 0 ETH | 0.01388122 | ||||
Claim Rewards | 17989361 | 534 days ago | IN | 0 ETH | 0.00773317 | ||||
Claim Rewards | 17980374 | 535 days ago | IN | 0 ETH | 0.01861483 | ||||
Claim Rewards | 17977066 | 535 days ago | IN | 0 ETH | 0.0080267 | ||||
Claim Rewards | 17973767 | 536 days ago | IN | 0 ETH | 0.00665537 | ||||
Claim Rewards | 17973223 | 536 days ago | IN | 0 ETH | 0.01419459 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
KarrotStolenPool
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: MIT pragma solidity ^0.8.19; /** ____ ____ /' | | \ / / | | \ \ / / | | | \ \ ( / | """" |\ \ | / / /^\ /^\ \ _| ~ | | | | | | ~ | |__O|__|O__| | /~~ \/ ~~\ / ( | ) \ _--_ /, \____/^\___/' \ _--_ /~ ~\ / -____-|_|_|-____-\ /~ ~\ /________|___/~~~~\___/~~~~\ __|________\ --~~~ ^ | | | | - : ~~~~~:~-_ ___-----~~~~~~~~| / `^-^-^' `^-^-^' : ~\ /' ____/--------| -- ; |/~~~------~~~~~~~~~| ; : : |----------/--------| : , ; . |---\\--------------| : - . : : |______________-__| : , , : /'~----___________| __ \\\ ^ ,, ;; ;; ;._-~ ~~~-----____________________________________----~~~ _______.___________. ______ __ _______ .__ __. .______ ______ ______ __ / | | / __ \ | | | ____|| \ | | | _ \ / __ \ / __ \ | | | (----`---| |----`| | | | | | | |__ | \| | | |_) | | | | | | | | | | | \ \ | | | | | | | | | __| | . ` | | ___/ | | | | | | | | | | .----) | | | | `--' | | `----.| |____ | |\ | | | | `--' | | `--' | | `----. |_______/ |__| \______/ |_______||_______||__| \__| | _| \______/ \______/ |_______| */ import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/utils/math/Math.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "./interfaces/IConfig.sol"; import "./interfaces/IAttackRewardCalculator.sol"; import "./interfaces/IKarrotsToken.sol"; /** StolenPool: where the stolen karrots go - claim tax (rabbits stealing karrots) from karrotChef are deposited here - every deposit is grouped into an epoch (1 day) based on time of deposit - rabbit attacks during this epoch are weighted by tier and stake claim to a portion of the epoch's deposited karrots - epoch ends, rewards are calculated, and rewards are claimable by attackers based on tier and number of successful attacks during that epoch - rewards are claimable only for previous epochs (not current) */ contract KarrotStolenPool is AccessControl, ReentrancyGuard { IConfig public config; address public outputAddress; bool public poolOpenTimestampSet; bool public stolenPoolAttackIsOpen = false; bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE"); uint16 public constant PERCENTAGE_DENOMINATOR = 10000; uint16 public attackBurnPercentage = 1000; //10% uint16 public rabbitTier1AttackRewardsWeight = 10000; //1x uint16 public rabbitTier2AttackRewardsWeight = 25000; //2.5x uint16 public rabbitTier3AttackRewardsWeight = 50000; //5x uint32 public poolOpenTimestamp; //start timestamp of karrotchef pool openings = epochs start here uint32 public immutable STOLEN_POOL_EPOCH_LENGTH; //1 day in production uint32 public totalAttacks; uint256 public totalClaimedRewardsForAll; uint256 public totalBurnedFromDeposits; uint256 public totalBurnedFromClaims; uint256 public totalMinted; mapping(uint256 => uint256) public epochBalances; mapping(address => Attack[]) public userAttacks; mapping(uint256 => EpochAttackStats) public epochAttackStats; mapping(address => UserAttackStats) public userAttackStats; mapping(address => uint256) public manuallyAddedRewards; ///@dev addresses that can virtually deposit karrots to this contract mapping(address => bool) public isApprovedDepositor; struct UserAttackStats { uint32 successfulAttacks; uint32 lastClaimEpoch; uint192 totalClaimedRewards; } struct EpochAttackStats { uint32 tier1; uint32 tier2; uint32 tier3; uint160 total; } struct Attack { uint216 epoch; //takes into account calcs for reward per attack by tier for this epoch (range of timestamps) uint32 rabbitId; uint8 tier; address user; } event AttackEvent(address indexed sender, uint256 tier); event StolenPoolRewardClaimed(address indexed sender, uint256 amount); event Deposit(address indexed sender, uint256 amount); error InvalidCaller(address caller, address expected); error CallerIsNotConfig(); error ForwardFailed(); error NoRewardsToClaim(); error PoolOpenTimestampNotSet(); error PoolOpenTimestampAlreadySet(); error FirstEpochHasNotPassedYet(uint256 remainingTimeUntilFirstEpochPasses); error InvalidRabbitTier(); error InvalidAllowance(); error AlreadyClaimedCurrentEpoch(); constructor(address _configAddress, uint32 _stolenPoolEpochLength) { config = IConfig(_configAddress); _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); _grantRole(ADMIN_ROLE, msg.sender); STOLEN_POOL_EPOCH_LENGTH = _stolenPoolEpochLength; } modifier approvedDepositor() { require(isApprovedDepositor[msg.sender], "Invalid caller"); _; } modifier attackIsOpen() { require(stolenPoolAttackIsOpen, "Attack is not open"); _; } modifier onlyConfig() { if (msg.sender != address(config) && !hasRole(ADMIN_ROLE,msg.sender) ) { revert CallerIsNotConfig(); } _; } /** * @dev virtually deposits karrots from either karrotChef or rabbit, * assuming that the _amount has either already been burned or hasn't been minted yet */ function virtualDeposit(uint256 _amount) public approvedDepositor { //add to this epoch's balance uint256 currentEpoch = getCurrentEpoch(); epochBalances[currentEpoch] += _amount; totalBurnedFromDeposits += _amount; emit Deposit(msg.sender, _amount); } // [!] check logik - make sure cooldown is controlled from the rabbit contract function attack(address _sender, uint256 _rabbitTier, uint256 _rabbitId) external attackIsOpen { //caller must be Rabbit contract address rabbitAddress = config.rabbitAddress(); if (msg.sender != rabbitAddress) { revert InvalidCaller(msg.sender, rabbitAddress); } uint256 currentEpoch = getCurrentEpoch(); //update overall attack stats for this epoch if (_rabbitTier == 1) { ++epochAttackStats[currentEpoch].tier1; } else if (_rabbitTier == 2) { ++epochAttackStats[currentEpoch].tier2; } else if (_rabbitTier == 3) { ++epochAttackStats[currentEpoch].tier3; } else { revert InvalidRabbitTier(); } ++epochAttackStats[currentEpoch].total; ++totalAttacks; //set successful attacks for this rabbit id/user and tier and epoch userAttacks[_sender].push(Attack(uint216(currentEpoch), uint32(_rabbitId), uint8(_rabbitTier), _sender)); ++userAttackStats[_sender].successfulAttacks; emit AttackEvent(_sender, _rabbitTier); } function claimRewards() external nonReentrant returns (uint256, uint256) { if(userAttackStats[msg.sender].lastClaimEpoch == uint32(getCurrentEpoch())) { revert AlreadyClaimedCurrentEpoch(); } uint256 totalRewardsForUser = getPretaxPendingRewards(msg.sender); manuallyAddedRewards[msg.sender] = 0; //reset to 0 after claim if (totalRewardsForUser == 0) { revert NoRewardsToClaim(); } uint256 burnAmount = Math.mulDiv( totalRewardsForUser, attackBurnPercentage, PERCENTAGE_DENOMINATOR ); //update last claim epoch to current epoch to prevent double claiming userAttackStats[msg.sender].lastClaimEpoch = uint32(getCurrentEpoch()); userAttackStats[msg.sender].totalClaimedRewards += uint192(totalRewardsForUser - burnAmount); totalClaimedRewardsForAll += totalRewardsForUser - burnAmount; // send remaining rewards to user totalMinted += totalRewardsForUser - burnAmount; IKarrotsToken(config.karrotsAddress()).mint(msg.sender, totalRewardsForUser - burnAmount); // update total burned totalBurnedFromClaims += burnAmount; emit StolenPoolRewardClaimed(msg.sender, totalRewardsForUser - burnAmount); return (totalRewardsForUser, burnAmount); } function getCurrentEpoch() public view returns (uint256) { return Math.mulDiv( block.timestamp - poolOpenTimestamp, 1, STOLEN_POOL_EPOCH_LENGTH ); } function getEpochLength() public view returns (uint256) { return STOLEN_POOL_EPOCH_LENGTH; } /// @dev get seconds until next epoch function getSecondsUntilNextEpoch() public view returns (uint256) { return STOLEN_POOL_EPOCH_LENGTH - ((block.timestamp - poolOpenTimestamp) % STOLEN_POOL_EPOCH_LENGTH); } function getCurrentEpochBalance() public view returns (uint256) { uint256 currentEpoch = getCurrentEpoch(); return epochBalances[currentEpoch]; } function getEpochBalance(uint256 _epoch) public view returns (uint256) { return epochBalances[_epoch]; } function getUserAttackEpochs(address _user) public view returns (uint256[] memory) { uint256[] memory epochs = new uint256[](userAttacks[_user].length); for (uint256 i = 0; i < userAttacks[_user].length; ++i) { epochs[i] = userAttacks[_user][i].epoch; } return epochs; } function getUserAttackRabbitId(uint256 _index) public view returns (uint256) { return userAttacks[msg.sender][_index].rabbitId; } function getUserAttackTier(uint256 _index) public view returns (uint256) { return userAttacks[msg.sender][_index].tier; } /** @dev calculate user rewards by summing up rewards from each epoch rewards from each epoch are calculated as: baseReward = (total karrots deposited this epoch) / (total successful attacks this epoch) where baseReward is scaled based on tier of rabbit attacked such that the relative earnings are: tier 1 = 1x, tier 2 = 2.5x, tier 3 = 5x */ function getPretaxPendingRewards(address _user) public view returns (uint256) { //claim rewards from lastClaimEpoch[_user] to currentEpoch uint256 currentEpoch = getCurrentEpoch(); uint256 lastClaimedEpoch = userAttackStats[_user].lastClaimEpoch; uint256 totalRewardsForUser; for (uint256 i = lastClaimedEpoch; i < currentEpoch; ++i) { //get total deposited karrots this epoch if(epochBalances[i] == 0) { continue; } (uint256 tier1RewardsPerAttack, uint256 tier2RewardsPerAttack, uint256 tier3RewardsPerAttack) = getPretaxPendingRewardsForEpoch(i); //now that I have the rewards per attack for each tier, I can calculate the total rewards for the user uint256 totalRewardCurrentEpoch = 0; for (uint256 j = 0; j < userAttacks[_user].length; ++j) { Attack memory thisAttack = userAttacks[_user][j]; if (thisAttack.epoch == i) { if (thisAttack.tier == 1) { totalRewardCurrentEpoch += tier1RewardsPerAttack; } else if (thisAttack.tier == 2) { totalRewardCurrentEpoch += tier2RewardsPerAttack; } else if (thisAttack.tier == 3) { totalRewardCurrentEpoch += tier3RewardsPerAttack; } } } totalRewardsForUser += totalRewardCurrentEpoch; } totalRewardsForUser += manuallyAddedRewards[_user]; return totalRewardsForUser; } function getPretaxPendingRewardsForEpoch(uint256 _epoch) public view returns (uint256, uint256, uint256) { //get total deposited karrots this epoch uint256 totalKarrotsDepositedCurrentEpoch = epochBalances[_epoch]; EpochAttackStats memory currentEpochStats = epochAttackStats[_epoch]; uint256 tier1Attacks = currentEpochStats.tier1; uint256 tier2Attacks = currentEpochStats.tier2; uint256 tier3Attacks = currentEpochStats.tier3; //get rewards per attack for each tier [tier1, tier2, tier3] uint256[] memory rewardsPerAttackByTier = IAttackRewardCalculator(config.attackRewardCalculatorAddress()).calculateRewardPerAttackByTier( tier1Attacks, tier2Attacks, tier3Attacks, rabbitTier1AttackRewardsWeight, rabbitTier2AttackRewardsWeight, rabbitTier3AttackRewardsWeight, totalKarrotsDepositedCurrentEpoch ); return (rewardsPerAttackByTier[0], rewardsPerAttackByTier[1], rewardsPerAttackByTier[2]); } function getPosttaxPendingRewards(address _user) public view returns (uint256) { uint256 pretaxRewards = getPretaxPendingRewards(_user); uint256 posttaxRewards = Math.mulDiv( pretaxRewards, PERCENTAGE_DENOMINATOR - attackBurnPercentage, PERCENTAGE_DENOMINATOR ); return posttaxRewards; } function getUserSuccessfulAttacks(address _user) public view returns (uint256) { return userAttackStats[_user].successfulAttacks; } function getUserLastClaimEpoch(address _user) public view returns (uint256) { return userAttackStats[_user].lastClaimEpoch; } function getUserTotalClaimedRewards(address _user) public view returns (uint256) { return userAttackStats[_user].totalClaimedRewards; } function getEpochTier1Attacks(uint256 _epoch) public view returns (uint256) { return epochAttackStats[_epoch].tier1; } function getEpochTier2Attacks(uint256 _epoch) public view returns (uint256) { return epochAttackStats[_epoch].tier2; } function getEpochTier3Attacks(uint256 _epoch) public view returns (uint256) { return epochAttackStats[_epoch].tier3; } function getEpochTotalAttacks(uint256 _epoch) public view returns (uint256) { return epochAttackStats[_epoch].total; } //========================================================================= // SETTERS/WITHDRAWALS //========================================================================= //corresponds to the call of karrotChef.openKarrotChefDeposits() function setStolenPoolOpenTimestamp() external onlyConfig { if (!poolOpenTimestampSet) { //set timestamp for the start of epochs poolOpenTimestamp = uint32(block.timestamp); poolOpenTimestampSet = true; } else { revert PoolOpenTimestampAlreadySet(); } } function setPoolOpenTimestampManual(uint32 _timestamp) external onlyRole(ADMIN_ROLE) { poolOpenTimestamp = _timestamp; } function setStolenPoolAttackIsOpen(bool _isOpen) external onlyConfig { stolenPoolAttackIsOpen = _isOpen; } function setAttackBurnPercentage(uint16 _percentage) external onlyConfig { attackBurnPercentage = _percentage; } function setIsApprovedDepositor(address _depositor, bool _isApproved) external onlyConfig { isApprovedDepositor[_depositor] = _isApproved; } //------------------------------------------------------------------------- function burnAndVirtualDeposit(uint256 _amount) external onlyRole(ADMIN_ROLE) { IKarrotsToken(config.karrotsAddress()).transferFrom(msg.sender, address(this), _amount); IKarrotsToken(config.karrotsAddress()).burn(_amount); virtualDeposit(_amount); } function setEpochBalanceManual(uint256 _epoch, uint256 _epochBalance) external onlyRole(ADMIN_ROLE) { epochBalances[_epoch] = _epochBalance; } function addToEpochBalanceManual(uint256 _epoch, uint256 _amount) external onlyRole(ADMIN_ROLE) { epochBalances[_epoch] += _amount; } function batchSetManuallyAddedRewards(address[] memory _users, uint256[] memory _amounts) external onlyRole(ADMIN_ROLE) { require(_users.length == _amounts.length, "Invalid input"); for (uint256 i = 0; i < _users.length; i++) { manuallyAddedRewards[_users[i]] = _amounts[i]; } } function batchAddToManuallyAddedRewards(address[] memory _users, uint256[] memory _amounts) external onlyRole(ADMIN_ROLE) { require(_users.length == _amounts.length, "Invalid input"); for (uint256 i = 0; i < _users.length; i++) { manuallyAddedRewards[_users[i]] += _amounts[i]; } } function setManuallyAddedRewardsForUser(address _user, uint256 _amount) public onlyRole(ADMIN_ROLE) { manuallyAddedRewards[_user] = _amount; } function addToManuallyAddedRewardsForUser(address _user, uint256 _amount) public onlyRole(ADMIN_ROLE) { manuallyAddedRewards[_user] += _amount; } //------------------------------------------------------------------------- function setConfigManagerAddress(address _configManagerAddress) external onlyRole(ADMIN_ROLE) { config = IConfig(_configManagerAddress); } function setOutputAddress(address _outputAddress) external onlyRole(ADMIN_ROLE) { outputAddress = _outputAddress; } function withdrawERC20FromContract(address _to, address _token) external onlyRole(ADMIN_ROLE) { bool os = IERC20(_token).transfer(_to, IERC20(_token).balanceOf(address(this))); if (!os) { revert ForwardFailed(); } } function withdrawEthFromContract() external onlyRole(ADMIN_ROLE) { require(outputAddress != address(0), "Payment splitter address not set"); (bool os, ) = payable(outputAddress).call{value: address(this).balance}(""); if (!os) { revert ForwardFailed(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ```solidity * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(account), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // 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; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; interface IConfig { function dexInterfacerAddress() external view returns (address); function karrotsAddress() external view returns (address); function karrotChefAddress() external view returns (address); function karrotStolenPoolAddress() external view returns (address); function karrotFullProtecAddress() external view returns (address); function karrotsPoolAddress() external view returns (address); function rabbitAddress() external view returns (address); function randomizerAddress() external view returns (address); function uniswapRouterAddress() external view returns (address); function uniswapFactoryAddress() external view returns (address); function treasuryAddress() external view returns (address); function treasuryBAddress() external view returns (address); function teamSplitterAddress() external view returns (address); function presaleDistributorAddress() external view returns (address); function airdropDistributorAddress() external view returns (address); function attackRewardCalculatorAddress() external view returns (address); }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.19; interface IAttackRewardCalculator { function calculateRewardPerAttackByTier( uint256 tier1Attacks, uint256 tier2Attacks, uint256 tier3Attacks, uint256 tier1Weight, uint256 tier2Weight, uint256 tier3Weight, uint256 totalKarrotsDepositedThisEpoch ) external view returns (uint256[] memory); }
//SPDX-License-Identifier: MIT pragma solidity 0.8.19; interface IKarrotsToken { function approve(address spender, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function addDexAddress(address _dexAddress) external; function removeDexAddress(address _dexAddress) external; function mint(address to, uint256 amount) external; function burn(uint256 amount) external; function burnFrom(address account, uint256 amount) external; function rebase(uint256 epoch, uint256 indexDelta, bool positive) external returns (uint256); function balanceOf(address account) external view returns (uint256); function totalSupply() external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); function transferUnderlying(address to, uint256 value) external returns (bool); function fragmentToKarrots(uint256 value) external view returns (uint256); function karrotsToFragment(uint256 karrots) external view returns (uint256); function balanceOfUnderlying(address who) external view returns (uint256); function setSellTaxRate(uint16 _sellTaxRate) external; function setBuyTaxRate(uint16 _buyTaxRate) external; function setMaxScaleFactorDecreasePercentagePerDebase(uint256 _maxScaleFactorDecreasePercentagePerDebase) external; function setTaxSwapAmountThreshold(uint256 _taxSwapAmountThreshold) external; function setDivertTaxToStolenPoolRate(uint256 _divertRate) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "remappings": [ "@chainlink/contracts/=lib/chainlink/contracts/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "foundry-devops/=lib/foundry-devops/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "openzeppelin/=lib/openzeppelin-contracts/contracts/" ], "optimizer": { "enabled": true, "runs": 200, "details": { "constantOptimizer": true, "yul": true, "yulDetails": { "stackAllocation": true, "optimizerSteps": "dhfoDgvulfnTUtnIf" } } }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": { "lib/foundry-devops/src/DevOpsTools.sol": { "DevOpsTools": "0x3fd2b64a587cc58117db334fbd51c58d256adac5" } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_configAddress","type":"address"},{"internalType":"uint32","name":"_stolenPoolEpochLength","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyClaimedCurrentEpoch","type":"error"},{"inputs":[],"name":"CallerIsNotConfig","type":"error"},{"inputs":[{"internalType":"uint256","name":"remainingTimeUntilFirstEpochPasses","type":"uint256"}],"name":"FirstEpochHasNotPassedYet","type":"error"},{"inputs":[],"name":"ForwardFailed","type":"error"},{"inputs":[],"name":"InvalidAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"expected","type":"address"}],"name":"InvalidCaller","type":"error"},{"inputs":[],"name":"InvalidRabbitTier","type":"error"},{"inputs":[],"name":"NoRewardsToClaim","type":"error"},{"inputs":[],"name":"PoolOpenTimestampAlreadySet","type":"error"},{"inputs":[],"name":"PoolOpenTimestampNotSet","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"tier","type":"uint256"}],"name":"AttackEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StolenPoolRewardClaimed","type":"event"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERCENTAGE_DENOMINATOR","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STOLEN_POOL_EPOCH_LENGTH","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"addToEpochBalanceManual","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"addToManuallyAddedRewardsForUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"uint256","name":"_rabbitTier","type":"uint256"},{"internalType":"uint256","name":"_rabbitId","type":"uint256"}],"name":"attack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"attackBurnPercentage","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"batchAddToManuallyAddedRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"batchSetManuallyAddedRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burnAndVirtualDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"config","outputs":[{"internalType":"contract IConfig","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochAttackStats","outputs":[{"internalType":"uint32","name":"tier1","type":"uint32"},{"internalType":"uint32","name":"tier2","type":"uint32"},{"internalType":"uint32","name":"tier3","type":"uint32"},{"internalType":"uint160","name":"total","type":"uint160"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochBalances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentEpochBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"}],"name":"getEpochBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEpochLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"}],"name":"getEpochTier1Attacks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"}],"name":"getEpochTier2Attacks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"}],"name":"getEpochTier3Attacks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"}],"name":"getEpochTotalAttacks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getPosttaxPendingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getPretaxPendingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"}],"name":"getPretaxPendingRewardsForEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSecondsUntilNextEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserAttackEpochs","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getUserAttackRabbitId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getUserAttackTier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserLastClaimEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserSuccessfulAttacks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserTotalClaimedRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isApprovedDepositor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"manuallyAddedRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"outputAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolOpenTimestamp","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolOpenTimestampSet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rabbitTier1AttackRewardsWeight","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rabbitTier2AttackRewardsWeight","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rabbitTier3AttackRewardsWeight","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_percentage","type":"uint16"}],"name":"setAttackBurnPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_configManagerAddress","type":"address"}],"name":"setConfigManagerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"},{"internalType":"uint256","name":"_epochBalance","type":"uint256"}],"name":"setEpochBalanceManual","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_depositor","type":"address"},{"internalType":"bool","name":"_isApproved","type":"bool"}],"name":"setIsApprovedDepositor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setManuallyAddedRewardsForUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_outputAddress","type":"address"}],"name":"setOutputAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_timestamp","type":"uint32"}],"name":"setPoolOpenTimestampManual","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isOpen","type":"bool"}],"name":"setStolenPoolAttackIsOpen","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setStolenPoolOpenTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stolenPoolAttackIsOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAttacks","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBurnedFromClaims","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBurnedFromDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalClaimedRewardsForAll","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userAttackStats","outputs":[{"internalType":"uint32","name":"successfulAttacks","type":"uint32"},{"internalType":"uint32","name":"lastClaimEpoch","type":"uint32"},{"internalType":"uint192","name":"totalClaimedRewards","type":"uint192"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userAttacks","outputs":[{"internalType":"uint216","name":"epoch","type":"uint216"},{"internalType":"uint32","name":"rabbitId","type":"uint32"},{"internalType":"uint8","name":"tier","type":"uint8"},{"internalType":"address","name":"user","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"virtualDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"address","name":"_token","type":"address"}],"name":"withdrawERC20FromContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawEthFromContract","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a060405260038054600160a81b600160f01b03191667186a0c3504e2007d60b31b1790553480156200003157600080fd5b5060405162003526380380620035268339810160408190526200005491620001c3565b60018055600280546001600160a01b0319166001600160a01b03841617905562000080600033620000bc565b620000ac7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177533620000bc565b63ffffffff166080525062000206565b620000c8828262000145565b62000141576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620001003390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff165b92915050565b60006001600160a01b0382166200016a565b6200018d8162000170565b81146200019957600080fd5b50565b80516200016a8162000182565b63ffffffff81166200018d565b80516200016a81620001a9565b60008060408385031215620001db57620001db600080fd5b6000620001e985856200019c565b9250506020620001fc85828601620001b6565b9150509250929050565b6080516132e86200023e600039600081816106c00152818161099001528181610b8701528181610bc90152611da701526132e86000f3fe608060405234801561001057600080fd5b50600436106103f15760003560e01c806365701b0d11610215578063b97dd9e211610125578063da0c2e23116100b8578063ea98fea611610087578063ea98fea614610a4d578063f0abb14d14610a6d578063f13ddbbd14610a80578063f6f0049614610aa3578063f76047da14610ab657600080fd5b8063da0c2e23146109dd578063db081a0b14610a13578063dd8dc5de14610a27578063decae39914610a3a57600080fd5b8063ce684b85116100f4578063ce684b851461097b578063cfe8a73b1461098e578063d080a9f0146109ba578063d547741f146109ca57600080fd5b8063b97dd9e2146108fa578063c6412cfc14610902578063cca41f4614610915578063cd7d88931461092857600080fd5b8063962f8006116101a8578063a80ce7ee11610177578063a80ce7ee14610896578063aef0004a146108a9578063af8e39c9146108c9578063b04ddbf0146108dc578063b3cd4254146108f157600080fd5b8063962f8006146108745780639ab725401461087d578063a217fddf14610885578063a2309ff81461088d57600080fd5b806379502c55116101e457806379502c551461081b5780637df3dbfc1461083b5780637e5cf4ce1461084e57806391d148541461086157600080fd5b806365701b0d146107d25780637352d47f146107da57806375b238fc146107e357806378b0b124146107f857600080fd5b806336568abe116103105780634b5e526e116102a357806355ffc2321161027257806355ffc232146107165780635612ba4b1461071e57806359665e6e1461074e5780635c2eaeff1461076357806361b41d081461077657600080fd5b80634b5e526e146106b25780634c76fb14146106bb5780634dc2489c146106e25780635001fa6a146106f657600080fd5b80633b6eaae0116102df5780633b6eaae0146106595780633fb0647e1461066c57806340c7e79b1461067f578063452ae3311461069f57600080fd5b806336568abe146105d4578063372500ab146105e757806339eb266c146105fd5780633a1b1fde1461062a57600080fd5b80632278a902116103885780632d40d452116103575780632d40d452146105775780632dea23e81461058a5780632f2ff15d146105ac57806333482482146105bf57600080fd5b80632278a902146104e6578063248a9ca3146104f95780632673b4571461051c5780632705bb911461055557600080fd5b80631318dddb116103c45780631318dddb1461049257806313296941146104a7578063148f106c146104cb5780631f63c807146104d357600080fd5b806301ffc9a7146103f65780630216c6a91461041f5780630bab3eb5146104525780631233c0c71461047f575b600080fd5b6104096104043660046125fe565b610ad6565b6040516104169190612629565b60405180910390f35b61044561042d366004612648565b6000908152600b602052604090205463ffffffff1690565b604051610416919061266f565b610445610460366004612648565b6000908152600b6020526040902054600160401b900463ffffffff1690565b61044561048d366004612648565b610b0d565b6104a56104a036600461267d565b610b4f565b005b6004546104be90600160201b900463ffffffff1681565b60405161041691906126c6565b610445610b7a565b6104456104e13660046126f9565b610bf3565b6104a56104f4366004612648565b610dcb565b610445610507366004612648565b60009081526020819052604090206001015490565b61044561052a3660046126f9565b6001600160a01b03166000908152600c6020526040902054600160401b90046001600160c01b031690565b610568610563366004612648565b610e8e565b6040516104169392919061271a565b6104456105853660046126f9565b611060565b60035461059f90600160b01b900461ffff1681565b604051610416919061274c565b6104a56105ba36600461275a565b6110a6565b60035461059f90600160c01b900461ffff1681565b6104a56105e236600461275a565b6110d0565b6105ef611106565b60405161041692919061278d565b61044561060b366004612648565b6000908152600b6020526040902054600160201b900463ffffffff1690565b6104456106383660046126f9565b6001600160a01b03166000908152600c602052604090205463ffffffff1690565b6104a56106673660046127bb565b6113d7565b6104a561067a36600461267d565b611450565b61044561068d3660046126f9565b600d6020526000908152604090205481565b6104a56106ad3660046127ee565b611490565b61044560065481565b6104be7f000000000000000000000000000000000000000000000000000000000000000081565b60035461040990600160a81b900460ff1681565b610445610704366004612648565b60009081526009602052604090205490565b6104456117f3565b61044561072c366004612648565b6000908152600b6020526040902054600160601b90046001600160a01b031690565b60035461059f90600160d01b900461ffff1681565b610445610771366004612648565b611813565b6107c2610784366004612648565b600b6020526000908152604090205463ffffffff80821691600160201b8104821691600160401b82041690600160601b90046001600160a01b031684565b604051610416949392919061284d565b6104a5611858565b61044560075481565b61044560008051602061329383398151915281565b61080b610806366004612882565b61190c565b60405161041694939291906128c5565b60025461082e906001600160a01b031681565b604051610416919061293c565b6104a5610849366004612648565b611973565b6104a561085c36600461295f565b611b52565b61040961086f36600461275a565b611bc2565b61044560055481565b6104a5611beb565b610445600081565b61044560085481565b6104a56108a4366004612af8565b611c8f565b6003546108bc906001600160a01b031681565b6040516104169190612b60565b6104a56108d7366004612882565b611d49565b60035461059f90600160e01b900461ffff1681565b61059f61271081565b610445611d89565b6104a5610910366004612b6e565b611dd1565b6104a5610923366004612af8565b611e3d565b61096c6109363660046126f9565b600c6020526000908152604090205463ffffffff80821691600160201b810490911690600160401b90046001600160c01b031683565b60405161041693929190612b9e565b6104a56109893660046126f9565b611f01565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff16610445565b6004546104be9063ffffffff1681565b6104a56109d836600461275a565b611f3c565b6104456109eb3660046126f9565b6001600160a01b03166000908152600c6020526040902054600160201b900463ffffffff1690565b60035461040990600160a01b900460ff1681565b6104a5610a353660046126f9565b611f61565b6104a5610a48366004612bdd565b611f9c565b610a60610a5b3660046126f9565b611fd1565b6040516104169190612c5c565b6104a5610a7b366004612882565b6120d2565b610409610a8e3660046126f9565b600e6020526000908152604090205460ff1681565b6104a5610ab1366004612c6d565b612107565b610445610ac4366004612648565b60096020526000908152604090205481565b60006001600160e01b03198216637965db0b60e01b1480610b0757506301ffc9a760e01b6001600160e01b03198316145b92915050565b336000908152600a60205260408120805483908110610b2e57610b2e612c8f565b6000918252602090912060029091020154600160f81b900460ff1692915050565b600080516020613293833981519152610b678161221e565b5060009182526009602052604090912055565b60045460009063ffffffff7f0000000000000000000000000000000000000000000000000000000000000000811691610bb4911642612cbb565b610bbe9190612ce4565b610bee9063ffffffff7f000000000000000000000000000000000000000000000000000000000000000016612cbb565b905090565b600080610bfe611d89565b6001600160a01b0384166000908152600c6020526040812054919250600160201b90910463ffffffff1690815b83811015610d9e5760008181526009602052604090205415610d8e576000806000610c5584610e8e565b9250925092506000805b6001600160a01b038b166000908152600a6020526040902054811015610d7c576001600160a01b038b166000908152600a60205260408120805483908110610ca957610ca9612c8f565b600091825260209182902060408051608081018252600290930290910180546001600160d81b03811680855263ffffffff600160d81b8304169585019590955260ff600160f81b9091041691830191909152600101546001600160a01b031660608201529150879003610d6b57806040015160ff16600103610d3657610d2f8684612cf8565b9250610d6b565b806040015160ff16600203610d4f57610d2f8584612cf8565b806040015160ff16600303610d6b57610d688484612cf8565b92505b50610d7581612d0b565b9050610c5f565b50610d878187612cf8565b9550505050505b610d9781612d0b565b9050610c2b565b506001600160a01b0385166000908152600d6020526040902054610dc29082612cf8565b95945050505050565b336000908152600e602052604090205460ff16610e035760405162461bcd60e51b8152600401610dfa90612d47565b60405180910390fd5b6000610e0d611d89565b905081600960008381526020019081526020016000206000828254610e329190612cf8565b925050819055508160066000828254610e4b9190612cf8565b909155505060405133907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c90610e8290859061266f565b60405180910390a25050565b600081815260096020908152604080832054600b83528184208251608081018452905463ffffffff808216808452600160201b83048216848801819052600160401b84049092168487018190526001600160a01b03600160601b90940484166060860152600254875163335a506960e21b815297518a998a99949693948a94939093169263cd6941a492600482810193928290030181865afa158015610f38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5c9190612d62565b60035460405163fe5beee760e01b81526001600160a01b03929092169163fe5beee791610fb59188918891889161ffff600160c01b8204811692600160d01b8304821692600160e01b9004909116908f90600401612d9c565b600060405180830381865afa158015610fd2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ffa9190810190612e82565b90508060008151811061100f5761100f612c8f565b60200260200101518160018151811061102a5761102a612c8f565b60200260200101518260028151811061104557611045612c8f565b60200260200101519850985098505050505050509193909250565b60008061106c83610bf3565b9050600061109e82600360169054906101000a900461ffff166127106110929190612ebd565b61ffff1661271061222b565b949350505050565b6000828152602081905260409020600101546110c18161221e565b6110cb83836122f3565b505050565b6001600160a01b03811633146110f85760405162461bcd60e51b8152600401610dfa90612edb565b6111028282612377565b5050565b6000806111116123dc565b611119611d89565b336000908152600c602052604090205463ffffffff918216600160201b9091049091160361115a576040516367a2c76160e01b815260040160405180910390fd5b600061116533610bf3565b336000908152600d6020526040812081905590915081900361119a576040516373380d9960e01b815260040160405180910390fd5b6003546000906111b9908390600160b01b900461ffff1661271061222b565b90506111c3611d89565b336000908152600c60205260409020805463ffffffff92909216600160201b0267ffffffff00000000199092169190911790556112008183612cbb565b336000908152600c60205260409020805460089061122f908490600160401b90046001600160c01b0316612f2e565b92506101000a8154816001600160c01b0302191690836001600160c01b03160217905550808261125f9190612cbb565b600560008282546112709190612cf8565b9091555061128090508183612cbb565b600860008282546112919190612cf8565b909155505060025460408051630a15a2e160e41b815290516001600160a01b039092169163a15a2e10916004808201926020929091908290030181865afa1580156112e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113049190612d62565b6001600160a01b03166340c10f193361131d8486612cbb565b6040518363ffffffff1660e01b815260040161133a929190612f51565b600060405180830381600087803b15801561135457600080fd5b505af1158015611368573d6000803e3d6000fd5b50505050806007600082825461137e9190612cf8565b909155503390507f18610bf761603ef73c33c6ea9801786397ef8d0a48a62ac3e867867e926668bf6113b08385612cbb565b6040516113bd919061266f565b60405180910390a290925090506113d360018055565b9091565b6002546001600160a01b03163314801590611407575061140560008051602061329383398151915233611bc2565b155b15611425576040516340e2203b60e01b815260040160405180910390fd5b6001600160a01b03919091166000908152600e60205260409020805460ff1916911515919091179055565b6000805160206132938339815191526114688161221e565b60008381526009602052604081208054849290611486908490612cf8565b9091555050505050565b600354600160a81b900460ff166114b95760405162461bcd60e51b8152600401610dfa90612f86565b600254604080516311c2d4ff60e11b815290516000926001600160a01b031691632385a9fe9160048083019260209291908290030181865afa158015611503573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115279190612d62565b9050336001600160a01b038216146115565733816040516302d9d9c960e31b8152600401610dfa929190612f96565b6000611560611d89565b9050836001036115af576000818152600b60205260408120805490919061158c9063ffffffff16612fb1565b91906101000a81548163ffffffff021916908363ffffffff16021790555061162a565b836002036115e0576000818152600b60205260409020805460049061158c90600160201b900463ffffffff16612fb1565b83600303611611576000818152600b60205260409020805460089061158c90600160401b900463ffffffff16612fb1565b604051633729fe5160e21b815260040160405180910390fd5b6000818152600b602052604090208054600c9061165690600160601b90046001600160a01b0316612fcd565b91906101000a8154816001600160a01b0302191690836001600160a01b0316021790555060048081819054906101000a900463ffffffff1661169790612fb1565b82546101009290920a63ffffffff8181021990931691831602179091556001600160a01b038681166000818152600a6020908152604080832081516080810183526001600160d81b0389811682528b891682860190815260ff8e8116848701908152606085018a8152865460018181018955978b52898b2096516002909102909601805494519251969095166001600160f81b031990941693909317600160d81b918d1691909102176001600160f81b0316600160f81b94909116939093029290921781559051910180546001600160a01b0319169190961617909455918152600c9091529081208054909261178d9116612fb1565b91906101000a81548163ffffffff021916908363ffffffff160217905550846001600160a01b03167fac6fb771dca7f96ce211192540d554ad82e5f3b86e2c9d506c03642879513741856040516117e4919061266f565b60405180910390a25050505050565b6000806117fe611d89565b60009081526009602052604090205492915050565b336000908152600a6020526040812080548390811061183457611834612c8f565b6000918252602090912060029091020154600160d81b900463ffffffff1692915050565b6000805160206132938339815191526118708161221e565b6003546001600160a01b03166118985760405162461bcd60e51b8152600401610dfa9061301f565b6003546040516000916001600160a01b03169047908381818185875af1925050503d80600081146118e5576040519150601f19603f3d011682016040523d82523d6000602084013e6118ea565b606091505b50509050806111025760405163096dc0e160e01b815260040160405180910390fd5b600a602052816000526040600020818154811061192857600080fd5b6000918252602090912060029091020180546001909101546001600160d81b0382169350600160d81b820463ffffffff169250600160f81b90910460ff16906001600160a01b031684565b60008051602061329383398151915261198b8161221e565b600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a029190612d62565b6001600160a01b03166323b872dd3330856040518463ffffffff1660e01b8152600401611a319392919061302f565b6020604051808303816000875af1158015611a50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a749190613055565b50600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ac8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aec9190612d62565b6001600160a01b03166342966c68836040518263ffffffff1660e01b8152600401611b17919061266f565b600060405180830381600087803b158015611b3157600080fd5b505af1158015611b45573d6000803e3d6000fd5b5050505061110282610dcb565b6002546001600160a01b03163314801590611b825750611b8060008051602061329383398151915233611bc2565b155b15611ba0576040516340e2203b60e01b815260040160405180910390fd5b6003805461ffff909216600160b01b0261ffff60b01b19909216919091179055565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6002546001600160a01b03163314801590611c1b5750611c1960008051602061329383398151915233611bc2565b155b15611c39576040516340e2203b60e01b815260040160405180910390fd5b600354600160a01b900460ff16611c76576004805463ffffffff421663ffffffff199091161790556003805460ff60a01b1916600160a01b179055565b60405163f1a5c21f60e01b815260040160405180910390fd5b600080516020613293833981519152611ca78161221e565b8151835114611cc85760405162461bcd60e51b8152600401610dfa90613098565b60005b8351811015611d4357828181518110611ce657611ce6612c8f565b6020026020010151600d6000868481518110611d0457611d04612c8f565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508080611d3b90612d0b565b915050611ccb565b50505050565b600080516020613293833981519152611d618161221e565b6001600160a01b0383166000908152600d602052604081208054849290611486908490612cf8565b600454600090610bee90611da39063ffffffff1642612cbb565b60017f000000000000000000000000000000000000000000000000000000000000000063ffffffff1661222b565b6002546001600160a01b03163314801590611e015750611dff60008051602061329383398151915233611bc2565b155b15611e1f576040516340e2203b60e01b815260040160405180910390fd5b60038054911515600160a81b0260ff60a81b19909216919091179055565b600080516020613293833981519152611e558161221e565b8151835114611e765760405162461bcd60e51b8152600401610dfa90613098565b60005b8351811015611d4357828181518110611e9457611e94612c8f565b6020026020010151600d6000868481518110611eb257611eb2612c8f565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000206000828254611ee99190612cf8565b90915550819050611ef981612d0b565b915050611e79565b600080516020613293833981519152611f198161221e565b50600380546001600160a01b0319166001600160a01b0392909216919091179055565b600082815260208190526040902060010154611f578161221e565b6110cb8383612377565b600080516020613293833981519152611f798161221e565b50600280546001600160a01b0319166001600160a01b0392909216919091179055565b600080516020613293833981519152611fb48161221e565b506004805463ffffffff191663ffffffff92909216919091179055565b6001600160a01b0381166000908152600a60205260408120546060919067ffffffffffffffff81111561200657612006612980565b60405190808252806020026020018201604052801561202f578160200160208202803683370190505b50905060005b6001600160a01b0384166000908152600a60205260409020548110156120cb576001600160a01b0384166000908152600a6020526040902080548290811061207f5761207f612c8f565b600091825260209091206002909102015482516001600160d81b03909116908390839081106120b0576120b0612c8f565b60209081029190910101526120c481612d0b565b9050612035565b5092915050565b6000805160206132938339815191526120ea8161221e565b506001600160a01b039091166000908152600d6020526040902055565b60008051602061329383398151915261211f8161221e565b6000826001600160a01b031663a9059cbb85856001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161215d9190612b60565b602060405180830381865afa15801561217a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061219e91906130a8565b6040518363ffffffff1660e01b81526004016121bb929190612f51565b6020604051808303816000875af11580156121da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121fe9190613055565b905080611d435760405163096dc0e160e01b815260040160405180910390fd5b6122288133612405565b50565b60008080600019858709858702925082811083820303915050806000036122655783828161225b5761225b612cce565b04925050506122ec565b8084116122845760405162461bcd60e51b8152600401610dfa906130f3565b600084868809851960019081018716968790049682860381900495909211909303600082900391909104909201919091029190911760038402600290811880860282030280860282030280860282030280860282030280860282030280860290910302029150505b9392505050565b6122fd8282611bc2565b611102576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556123333390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6123818282611bc2565b15611102576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6002600154036123fe5760405162461bcd60e51b8152600401610dfa90613135565b6002600155565b61240f8282611bc2565b6111025761241c8161245e565b612427836020612470565b60405160200161243892919061318b565b60408051601f198184030181529082905262461bcd60e51b8252610dfa91600401613213565b6060610b076001600160a01b03831660145b6060600061247f836002613224565b61248a906002612cf8565b67ffffffffffffffff8111156124a2576124a2612980565b6040519080825280601f01601f1916602001820160405280156124cc576020820181803683370190505b509050600360fc1b816000815181106124e7576124e7612c8f565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061251657612516612c8f565b60200101906001600160f81b031916908160001a905350600061253a846002613224565b612545906001612cf8565b90505b60018111156125bd576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061257957612579612c8f565b1a60f81b82828151811061258f5761258f612c8f565b60200101906001600160f81b031916908160001a90535060049490941c936125b68161323b565b9050612548565b5083156122ec5760405162461bcd60e51b8152600401610dfa90613282565b6001600160e01b031981165b811461222857600080fd5b8035610b07816125dc565b60006020828403121561261357612613600080fd5b600061109e84846125f3565b8015155b82525050565b60208101610b07828461261f565b806125e8565b8035610b0781612637565b60006020828403121561265d5761265d600080fd5b600061109e848461263d565b80612623565b60208101610b078284612669565b6000806040838503121561269357612693600080fd5b600061269f858561263d565b92505060206126b08582860161263d565b9150509250929050565b63ffffffff8116612623565b60208101610b0782846126ba565b60006001600160a01b038216610b07565b6125e8816126d4565b8035610b07816126e5565b60006020828403121561270e5761270e600080fd5b600061109e84846126ee565b606081016127288286612669565b6127356020830185612669565b61109e6040830184612669565b61ffff8116612623565b60208101610b078284612742565b6000806040838503121561277057612770600080fd5b600061277c858561263d565b92505060206126b0858286016126ee565b6040810161279b8285612669565b6122ec6020830184612669565b8015156125e8565b8035610b07816127a8565b600080604083850312156127d1576127d1600080fd5b60006127dd85856126ee565b92505060206126b0858286016127b0565b60008060006060848603121561280657612806600080fd5b600061281286866126ee565b93505060206128238682870161263d565b92505060406128348682870161263d565b9150509250925092565b6001600160a01b038116612623565b6080810161285b82876126ba565b61286860208301866126ba565b61287560408301856126ba565b610dc2606083018461283e565b6000806040838503121561289857612898600080fd5b600061269f85856126ee565b6001600160d81b038116612623565b60ff8116612623565b612623816126d4565b608081016128d382876128a4565b6128e060208301866126ba565b6128ed60408301856128b3565b610dc260608301846128bc565b6000610b076001600160a01b038316612911565b90565b6001600160a01b031690565b6000610b07826128fa565b6000610b078261291d565b61262381612928565b60208101610b078284612933565b61ffff81166125e8565b8035610b078161294a565b60006020828403121561297457612974600080fd5b600061109e8484612954565b634e487b7160e01b600052604160045260246000fd5b601f19601f830116810181811067ffffffffffffffff821117156129bc576129bc612980565b6040525050565b60006129ce60405190565b90506129da8282612996565b919050565b600067ffffffffffffffff8211156129f9576129f9612980565b5060209081020190565b6000612a16612a11846129df565b6129c3565b83815290506020808201908402830185811115612a3557612a35600080fd5b835b81811015612a5757612a4987826126ee565b835260209283019201612a37565b5050509392505050565b600082601f830112612a7557612a75600080fd5b813561109e848260208601612a03565b6000612a93612a11846129df565b83815290506020808201908402830185811115612ab257612ab2600080fd5b835b81811015612a5757612ac6878261263d565b835260209283019201612ab4565b600082601f830112612ae857612ae8600080fd5b813561109e848260208601612a85565b60008060408385031215612b0e57612b0e600080fd5b823567ffffffffffffffff811115612b2857612b28600080fd5b612b3485828601612a61565b925050602083013567ffffffffffffffff811115612b5457612b54600080fd5b6126b085828601612ad4565b60208101610b0782846128bc565b600060208284031215612b8357612b83600080fd5b600061109e84846127b0565b6001600160c01b038116612623565b60608101612bac82866126ba565b612bb960208301856126ba565b61109e6040830184612b8f565b63ffffffff81166125e8565b8035610b0781612bc6565b600060208284031215612bf257612bf2600080fd5b600061109e8484612bd2565b612c088282612669565b5060200190565b60200190565b6000612c1f825190565b808452602093840193830160005b82811015612c52578151612c418782612bfe565b965050602082019150600101612c2d565b5093949350505050565b602080825281016122ec8184612c15565b60008060408385031215612c8357612c83600080fd5b600061277c85856126ee565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115610b0757610b07612ca5565b634e487b7160e01b600052601260045260246000fd5b600082612cf357612cf3612cce565b500690565b80820180821115610b0757610b07612ca5565b600060018201612d1d57612d1d612ca5565b5060010190565b600e8152602081016d24b73b30b634b21031b0b63632b960911b81529050612c0f565b60208082528101610b0781612d24565b8051610b07816126e5565b600060208284031215612d7757612d77600080fd5b600061109e8484612d57565b6000610b0761290e61ffff841681565b61262381612d83565b60e08101612daa828a612669565b612db76020830189612669565b612dc46040830188612669565b612dd16060830187612d93565b612dde6080830186612d93565b612deb60a0830185612d93565b612df860c0830184612669565b98975050505050505050565b8051610b0781612637565b6000612e1d612a11846129df565b83815290506020808201908402830185811115612e3c57612e3c600080fd5b835b81811015612a5757612e508782612e04565b835260209283019201612e3e565b600082601f830112612e7257612e72600080fd5b815161109e848260208601612e0f565b600060208284031215612e9757612e97600080fd5b815167ffffffffffffffff811115612eb157612eb1600080fd5b61109e84828501612e5e565b61ffff918216919081169082820390811115610b0757610b07612ca5565b60208082528101610b0781602f81527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560208201526e103937b632b9903337b91039b2b63360891b604082015260600190565b6001600160c01b03918216919081169082820190811115610b0757610b07612ca5565b6040810161279b82856128bc565b60128152602081017120ba3a30b1b59034b9903737ba1037b832b760711b81529050612c0f565b60208082528101610b0781612f5f565b60408101612fa482856128bc565b6122ec60208301846128bc565b63ffffffff16600063fffffffe198201612d1d57612d1d612ca5565b6001600160a01b031660006002600160a01b03198201612d1d57612d1d612ca5565b60208082527f5061796d656e742073706c69747465722061646472657373206e6f74207365749101908152612c0f565b60208082528101610b0781612fef565b6060810161303d82866128bc565b61273560208301856128bc565b8051610b07816127a8565b60006020828403121561306a5761306a600080fd5b600061109e848461304a565b600d8152602081016c125b9d985b1a59081a5b9c1d5d609a1b81529050612c0f565b60208082528101610b0781613076565b6000602082840312156130bd576130bd600080fd5b600061109e8484612e04565b6015815260208101744d6174683a206d756c446976206f766572666c6f7760581b81529050612c0f565b60208082528101610b07816130c9565b601f8152602081017f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081529050612c0f565b60208082528101610b0781613103565b60005b83811015613160578181015183820152602001613148565b50506000910152565b6000613173825190565b613181818560208601613145565b9290920192915050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526017016131bb8184613169565b7001034b99036b4b9b9b4b733903937b6329607d1b815260110190506122ec8183613169565b60006131eb825190565b808452602084019350613202818560208601613145565b601f01601f19169290920192915050565b602080825281016122ec81846131e1565b8181028115828204841417610b0757610b07612ca5565b60008161324a5761324a612ca5565b506000190190565b60208082527f537472696e67733a20686578206c656e67746820696e73756666696369656e749101908152612c0f565b60208082528101610b078161325256fea49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775a2646970667358221220cd42eedfd7fcf6ee3af4d32ec98c043eb40d0330f0d4c2eecb59e93bdc0f31f964736f6c634300081300330000000000000000000000001b7d040a501f19f1e28ed9fe58e307a9516ee7330000000000000000000000000000000000000000000000000000000000015180
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103f15760003560e01c806365701b0d11610215578063b97dd9e211610125578063da0c2e23116100b8578063ea98fea611610087578063ea98fea614610a4d578063f0abb14d14610a6d578063f13ddbbd14610a80578063f6f0049614610aa3578063f76047da14610ab657600080fd5b8063da0c2e23146109dd578063db081a0b14610a13578063dd8dc5de14610a27578063decae39914610a3a57600080fd5b8063ce684b85116100f4578063ce684b851461097b578063cfe8a73b1461098e578063d080a9f0146109ba578063d547741f146109ca57600080fd5b8063b97dd9e2146108fa578063c6412cfc14610902578063cca41f4614610915578063cd7d88931461092857600080fd5b8063962f8006116101a8578063a80ce7ee11610177578063a80ce7ee14610896578063aef0004a146108a9578063af8e39c9146108c9578063b04ddbf0146108dc578063b3cd4254146108f157600080fd5b8063962f8006146108745780639ab725401461087d578063a217fddf14610885578063a2309ff81461088d57600080fd5b806379502c55116101e457806379502c551461081b5780637df3dbfc1461083b5780637e5cf4ce1461084e57806391d148541461086157600080fd5b806365701b0d146107d25780637352d47f146107da57806375b238fc146107e357806378b0b124146107f857600080fd5b806336568abe116103105780634b5e526e116102a357806355ffc2321161027257806355ffc232146107165780635612ba4b1461071e57806359665e6e1461074e5780635c2eaeff1461076357806361b41d081461077657600080fd5b80634b5e526e146106b25780634c76fb14146106bb5780634dc2489c146106e25780635001fa6a146106f657600080fd5b80633b6eaae0116102df5780633b6eaae0146106595780633fb0647e1461066c57806340c7e79b1461067f578063452ae3311461069f57600080fd5b806336568abe146105d4578063372500ab146105e757806339eb266c146105fd5780633a1b1fde1461062a57600080fd5b80632278a902116103885780632d40d452116103575780632d40d452146105775780632dea23e81461058a5780632f2ff15d146105ac57806333482482146105bf57600080fd5b80632278a902146104e6578063248a9ca3146104f95780632673b4571461051c5780632705bb911461055557600080fd5b80631318dddb116103c45780631318dddb1461049257806313296941146104a7578063148f106c146104cb5780631f63c807146104d357600080fd5b806301ffc9a7146103f65780630216c6a91461041f5780630bab3eb5146104525780631233c0c71461047f575b600080fd5b6104096104043660046125fe565b610ad6565b6040516104169190612629565b60405180910390f35b61044561042d366004612648565b6000908152600b602052604090205463ffffffff1690565b604051610416919061266f565b610445610460366004612648565b6000908152600b6020526040902054600160401b900463ffffffff1690565b61044561048d366004612648565b610b0d565b6104a56104a036600461267d565b610b4f565b005b6004546104be90600160201b900463ffffffff1681565b60405161041691906126c6565b610445610b7a565b6104456104e13660046126f9565b610bf3565b6104a56104f4366004612648565b610dcb565b610445610507366004612648565b60009081526020819052604090206001015490565b61044561052a3660046126f9565b6001600160a01b03166000908152600c6020526040902054600160401b90046001600160c01b031690565b610568610563366004612648565b610e8e565b6040516104169392919061271a565b6104456105853660046126f9565b611060565b60035461059f90600160b01b900461ffff1681565b604051610416919061274c565b6104a56105ba36600461275a565b6110a6565b60035461059f90600160c01b900461ffff1681565b6104a56105e236600461275a565b6110d0565b6105ef611106565b60405161041692919061278d565b61044561060b366004612648565b6000908152600b6020526040902054600160201b900463ffffffff1690565b6104456106383660046126f9565b6001600160a01b03166000908152600c602052604090205463ffffffff1690565b6104a56106673660046127bb565b6113d7565b6104a561067a36600461267d565b611450565b61044561068d3660046126f9565b600d6020526000908152604090205481565b6104a56106ad3660046127ee565b611490565b61044560065481565b6104be7f000000000000000000000000000000000000000000000000000000000001518081565b60035461040990600160a81b900460ff1681565b610445610704366004612648565b60009081526009602052604090205490565b6104456117f3565b61044561072c366004612648565b6000908152600b6020526040902054600160601b90046001600160a01b031690565b60035461059f90600160d01b900461ffff1681565b610445610771366004612648565b611813565b6107c2610784366004612648565b600b6020526000908152604090205463ffffffff80821691600160201b8104821691600160401b82041690600160601b90046001600160a01b031684565b604051610416949392919061284d565b6104a5611858565b61044560075481565b61044560008051602061329383398151915281565b61080b610806366004612882565b61190c565b60405161041694939291906128c5565b60025461082e906001600160a01b031681565b604051610416919061293c565b6104a5610849366004612648565b611973565b6104a561085c36600461295f565b611b52565b61040961086f36600461275a565b611bc2565b61044560055481565b6104a5611beb565b610445600081565b61044560085481565b6104a56108a4366004612af8565b611c8f565b6003546108bc906001600160a01b031681565b6040516104169190612b60565b6104a56108d7366004612882565b611d49565b60035461059f90600160e01b900461ffff1681565b61059f61271081565b610445611d89565b6104a5610910366004612b6e565b611dd1565b6104a5610923366004612af8565b611e3d565b61096c6109363660046126f9565b600c6020526000908152604090205463ffffffff80821691600160201b810490911690600160401b90046001600160c01b031683565b60405161041693929190612b9e565b6104a56109893660046126f9565b611f01565b7f000000000000000000000000000000000000000000000000000000000001518063ffffffff16610445565b6004546104be9063ffffffff1681565b6104a56109d836600461275a565b611f3c565b6104456109eb3660046126f9565b6001600160a01b03166000908152600c6020526040902054600160201b900463ffffffff1690565b60035461040990600160a01b900460ff1681565b6104a5610a353660046126f9565b611f61565b6104a5610a48366004612bdd565b611f9c565b610a60610a5b3660046126f9565b611fd1565b6040516104169190612c5c565b6104a5610a7b366004612882565b6120d2565b610409610a8e3660046126f9565b600e6020526000908152604090205460ff1681565b6104a5610ab1366004612c6d565b612107565b610445610ac4366004612648565b60096020526000908152604090205481565b60006001600160e01b03198216637965db0b60e01b1480610b0757506301ffc9a760e01b6001600160e01b03198316145b92915050565b336000908152600a60205260408120805483908110610b2e57610b2e612c8f565b6000918252602090912060029091020154600160f81b900460ff1692915050565b600080516020613293833981519152610b678161221e565b5060009182526009602052604090912055565b60045460009063ffffffff7f0000000000000000000000000000000000000000000000000000000000015180811691610bb4911642612cbb565b610bbe9190612ce4565b610bee9063ffffffff7f000000000000000000000000000000000000000000000000000000000001518016612cbb565b905090565b600080610bfe611d89565b6001600160a01b0384166000908152600c6020526040812054919250600160201b90910463ffffffff1690815b83811015610d9e5760008181526009602052604090205415610d8e576000806000610c5584610e8e565b9250925092506000805b6001600160a01b038b166000908152600a6020526040902054811015610d7c576001600160a01b038b166000908152600a60205260408120805483908110610ca957610ca9612c8f565b600091825260209182902060408051608081018252600290930290910180546001600160d81b03811680855263ffffffff600160d81b8304169585019590955260ff600160f81b9091041691830191909152600101546001600160a01b031660608201529150879003610d6b57806040015160ff16600103610d3657610d2f8684612cf8565b9250610d6b565b806040015160ff16600203610d4f57610d2f8584612cf8565b806040015160ff16600303610d6b57610d688484612cf8565b92505b50610d7581612d0b565b9050610c5f565b50610d878187612cf8565b9550505050505b610d9781612d0b565b9050610c2b565b506001600160a01b0385166000908152600d6020526040902054610dc29082612cf8565b95945050505050565b336000908152600e602052604090205460ff16610e035760405162461bcd60e51b8152600401610dfa90612d47565b60405180910390fd5b6000610e0d611d89565b905081600960008381526020019081526020016000206000828254610e329190612cf8565b925050819055508160066000828254610e4b9190612cf8565b909155505060405133907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c90610e8290859061266f565b60405180910390a25050565b600081815260096020908152604080832054600b83528184208251608081018452905463ffffffff808216808452600160201b83048216848801819052600160401b84049092168487018190526001600160a01b03600160601b90940484166060860152600254875163335a506960e21b815297518a998a99949693948a94939093169263cd6941a492600482810193928290030181865afa158015610f38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5c9190612d62565b60035460405163fe5beee760e01b81526001600160a01b03929092169163fe5beee791610fb59188918891889161ffff600160c01b8204811692600160d01b8304821692600160e01b9004909116908f90600401612d9c565b600060405180830381865afa158015610fd2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ffa9190810190612e82565b90508060008151811061100f5761100f612c8f565b60200260200101518160018151811061102a5761102a612c8f565b60200260200101518260028151811061104557611045612c8f565b60200260200101519850985098505050505050509193909250565b60008061106c83610bf3565b9050600061109e82600360169054906101000a900461ffff166127106110929190612ebd565b61ffff1661271061222b565b949350505050565b6000828152602081905260409020600101546110c18161221e565b6110cb83836122f3565b505050565b6001600160a01b03811633146110f85760405162461bcd60e51b8152600401610dfa90612edb565b6111028282612377565b5050565b6000806111116123dc565b611119611d89565b336000908152600c602052604090205463ffffffff918216600160201b9091049091160361115a576040516367a2c76160e01b815260040160405180910390fd5b600061116533610bf3565b336000908152600d6020526040812081905590915081900361119a576040516373380d9960e01b815260040160405180910390fd5b6003546000906111b9908390600160b01b900461ffff1661271061222b565b90506111c3611d89565b336000908152600c60205260409020805463ffffffff92909216600160201b0267ffffffff00000000199092169190911790556112008183612cbb565b336000908152600c60205260409020805460089061122f908490600160401b90046001600160c01b0316612f2e565b92506101000a8154816001600160c01b0302191690836001600160c01b03160217905550808261125f9190612cbb565b600560008282546112709190612cf8565b9091555061128090508183612cbb565b600860008282546112919190612cf8565b909155505060025460408051630a15a2e160e41b815290516001600160a01b039092169163a15a2e10916004808201926020929091908290030181865afa1580156112e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113049190612d62565b6001600160a01b03166340c10f193361131d8486612cbb565b6040518363ffffffff1660e01b815260040161133a929190612f51565b600060405180830381600087803b15801561135457600080fd5b505af1158015611368573d6000803e3d6000fd5b50505050806007600082825461137e9190612cf8565b909155503390507f18610bf761603ef73c33c6ea9801786397ef8d0a48a62ac3e867867e926668bf6113b08385612cbb565b6040516113bd919061266f565b60405180910390a290925090506113d360018055565b9091565b6002546001600160a01b03163314801590611407575061140560008051602061329383398151915233611bc2565b155b15611425576040516340e2203b60e01b815260040160405180910390fd5b6001600160a01b03919091166000908152600e60205260409020805460ff1916911515919091179055565b6000805160206132938339815191526114688161221e565b60008381526009602052604081208054849290611486908490612cf8565b9091555050505050565b600354600160a81b900460ff166114b95760405162461bcd60e51b8152600401610dfa90612f86565b600254604080516311c2d4ff60e11b815290516000926001600160a01b031691632385a9fe9160048083019260209291908290030181865afa158015611503573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115279190612d62565b9050336001600160a01b038216146115565733816040516302d9d9c960e31b8152600401610dfa929190612f96565b6000611560611d89565b9050836001036115af576000818152600b60205260408120805490919061158c9063ffffffff16612fb1565b91906101000a81548163ffffffff021916908363ffffffff16021790555061162a565b836002036115e0576000818152600b60205260409020805460049061158c90600160201b900463ffffffff16612fb1565b83600303611611576000818152600b60205260409020805460089061158c90600160401b900463ffffffff16612fb1565b604051633729fe5160e21b815260040160405180910390fd5b6000818152600b602052604090208054600c9061165690600160601b90046001600160a01b0316612fcd565b91906101000a8154816001600160a01b0302191690836001600160a01b0316021790555060048081819054906101000a900463ffffffff1661169790612fb1565b82546101009290920a63ffffffff8181021990931691831602179091556001600160a01b038681166000818152600a6020908152604080832081516080810183526001600160d81b0389811682528b891682860190815260ff8e8116848701908152606085018a8152865460018181018955978b52898b2096516002909102909601805494519251969095166001600160f81b031990941693909317600160d81b918d1691909102176001600160f81b0316600160f81b94909116939093029290921781559051910180546001600160a01b0319169190961617909455918152600c9091529081208054909261178d9116612fb1565b91906101000a81548163ffffffff021916908363ffffffff160217905550846001600160a01b03167fac6fb771dca7f96ce211192540d554ad82e5f3b86e2c9d506c03642879513741856040516117e4919061266f565b60405180910390a25050505050565b6000806117fe611d89565b60009081526009602052604090205492915050565b336000908152600a6020526040812080548390811061183457611834612c8f565b6000918252602090912060029091020154600160d81b900463ffffffff1692915050565b6000805160206132938339815191526118708161221e565b6003546001600160a01b03166118985760405162461bcd60e51b8152600401610dfa9061301f565b6003546040516000916001600160a01b03169047908381818185875af1925050503d80600081146118e5576040519150601f19603f3d011682016040523d82523d6000602084013e6118ea565b606091505b50509050806111025760405163096dc0e160e01b815260040160405180910390fd5b600a602052816000526040600020818154811061192857600080fd5b6000918252602090912060029091020180546001909101546001600160d81b0382169350600160d81b820463ffffffff169250600160f81b90910460ff16906001600160a01b031684565b60008051602061329383398151915261198b8161221e565b600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119de573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a029190612d62565b6001600160a01b03166323b872dd3330856040518463ffffffff1660e01b8152600401611a319392919061302f565b6020604051808303816000875af1158015611a50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a749190613055565b50600260009054906101000a90046001600160a01b03166001600160a01b031663a15a2e106040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ac8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aec9190612d62565b6001600160a01b03166342966c68836040518263ffffffff1660e01b8152600401611b17919061266f565b600060405180830381600087803b158015611b3157600080fd5b505af1158015611b45573d6000803e3d6000fd5b5050505061110282610dcb565b6002546001600160a01b03163314801590611b825750611b8060008051602061329383398151915233611bc2565b155b15611ba0576040516340e2203b60e01b815260040160405180910390fd5b6003805461ffff909216600160b01b0261ffff60b01b19909216919091179055565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6002546001600160a01b03163314801590611c1b5750611c1960008051602061329383398151915233611bc2565b155b15611c39576040516340e2203b60e01b815260040160405180910390fd5b600354600160a01b900460ff16611c76576004805463ffffffff421663ffffffff199091161790556003805460ff60a01b1916600160a01b179055565b60405163f1a5c21f60e01b815260040160405180910390fd5b600080516020613293833981519152611ca78161221e565b8151835114611cc85760405162461bcd60e51b8152600401610dfa90613098565b60005b8351811015611d4357828181518110611ce657611ce6612c8f565b6020026020010151600d6000868481518110611d0457611d04612c8f565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508080611d3b90612d0b565b915050611ccb565b50505050565b600080516020613293833981519152611d618161221e565b6001600160a01b0383166000908152600d602052604081208054849290611486908490612cf8565b600454600090610bee90611da39063ffffffff1642612cbb565b60017f000000000000000000000000000000000000000000000000000000000001518063ffffffff1661222b565b6002546001600160a01b03163314801590611e015750611dff60008051602061329383398151915233611bc2565b155b15611e1f576040516340e2203b60e01b815260040160405180910390fd5b60038054911515600160a81b0260ff60a81b19909216919091179055565b600080516020613293833981519152611e558161221e565b8151835114611e765760405162461bcd60e51b8152600401610dfa90613098565b60005b8351811015611d4357828181518110611e9457611e94612c8f565b6020026020010151600d6000868481518110611eb257611eb2612c8f565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000206000828254611ee99190612cf8565b90915550819050611ef981612d0b565b915050611e79565b600080516020613293833981519152611f198161221e565b50600380546001600160a01b0319166001600160a01b0392909216919091179055565b600082815260208190526040902060010154611f578161221e565b6110cb8383612377565b600080516020613293833981519152611f798161221e565b50600280546001600160a01b0319166001600160a01b0392909216919091179055565b600080516020613293833981519152611fb48161221e565b506004805463ffffffff191663ffffffff92909216919091179055565b6001600160a01b0381166000908152600a60205260408120546060919067ffffffffffffffff81111561200657612006612980565b60405190808252806020026020018201604052801561202f578160200160208202803683370190505b50905060005b6001600160a01b0384166000908152600a60205260409020548110156120cb576001600160a01b0384166000908152600a6020526040902080548290811061207f5761207f612c8f565b600091825260209091206002909102015482516001600160d81b03909116908390839081106120b0576120b0612c8f565b60209081029190910101526120c481612d0b565b9050612035565b5092915050565b6000805160206132938339815191526120ea8161221e565b506001600160a01b039091166000908152600d6020526040902055565b60008051602061329383398151915261211f8161221e565b6000826001600160a01b031663a9059cbb85856001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161215d9190612b60565b602060405180830381865afa15801561217a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061219e91906130a8565b6040518363ffffffff1660e01b81526004016121bb929190612f51565b6020604051808303816000875af11580156121da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121fe9190613055565b905080611d435760405163096dc0e160e01b815260040160405180910390fd5b6122288133612405565b50565b60008080600019858709858702925082811083820303915050806000036122655783828161225b5761225b612cce565b04925050506122ec565b8084116122845760405162461bcd60e51b8152600401610dfa906130f3565b600084868809851960019081018716968790049682860381900495909211909303600082900391909104909201919091029190911760038402600290811880860282030280860282030280860282030280860282030280860282030280860290910302029150505b9392505050565b6122fd8282611bc2565b611102576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556123333390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6123818282611bc2565b15611102576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6002600154036123fe5760405162461bcd60e51b8152600401610dfa90613135565b6002600155565b61240f8282611bc2565b6111025761241c8161245e565b612427836020612470565b60405160200161243892919061318b565b60408051601f198184030181529082905262461bcd60e51b8252610dfa91600401613213565b6060610b076001600160a01b03831660145b6060600061247f836002613224565b61248a906002612cf8565b67ffffffffffffffff8111156124a2576124a2612980565b6040519080825280601f01601f1916602001820160405280156124cc576020820181803683370190505b509050600360fc1b816000815181106124e7576124e7612c8f565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061251657612516612c8f565b60200101906001600160f81b031916908160001a905350600061253a846002613224565b612545906001612cf8565b90505b60018111156125bd576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061257957612579612c8f565b1a60f81b82828151811061258f5761258f612c8f565b60200101906001600160f81b031916908160001a90535060049490941c936125b68161323b565b9050612548565b5083156122ec5760405162461bcd60e51b8152600401610dfa90613282565b6001600160e01b031981165b811461222857600080fd5b8035610b07816125dc565b60006020828403121561261357612613600080fd5b600061109e84846125f3565b8015155b82525050565b60208101610b07828461261f565b806125e8565b8035610b0781612637565b60006020828403121561265d5761265d600080fd5b600061109e848461263d565b80612623565b60208101610b078284612669565b6000806040838503121561269357612693600080fd5b600061269f858561263d565b92505060206126b08582860161263d565b9150509250929050565b63ffffffff8116612623565b60208101610b0782846126ba565b60006001600160a01b038216610b07565b6125e8816126d4565b8035610b07816126e5565b60006020828403121561270e5761270e600080fd5b600061109e84846126ee565b606081016127288286612669565b6127356020830185612669565b61109e6040830184612669565b61ffff8116612623565b60208101610b078284612742565b6000806040838503121561277057612770600080fd5b600061277c858561263d565b92505060206126b0858286016126ee565b6040810161279b8285612669565b6122ec6020830184612669565b8015156125e8565b8035610b07816127a8565b600080604083850312156127d1576127d1600080fd5b60006127dd85856126ee565b92505060206126b0858286016127b0565b60008060006060848603121561280657612806600080fd5b600061281286866126ee565b93505060206128238682870161263d565b92505060406128348682870161263d565b9150509250925092565b6001600160a01b038116612623565b6080810161285b82876126ba565b61286860208301866126ba565b61287560408301856126ba565b610dc2606083018461283e565b6000806040838503121561289857612898600080fd5b600061269f85856126ee565b6001600160d81b038116612623565b60ff8116612623565b612623816126d4565b608081016128d382876128a4565b6128e060208301866126ba565b6128ed60408301856128b3565b610dc260608301846128bc565b6000610b076001600160a01b038316612911565b90565b6001600160a01b031690565b6000610b07826128fa565b6000610b078261291d565b61262381612928565b60208101610b078284612933565b61ffff81166125e8565b8035610b078161294a565b60006020828403121561297457612974600080fd5b600061109e8484612954565b634e487b7160e01b600052604160045260246000fd5b601f19601f830116810181811067ffffffffffffffff821117156129bc576129bc612980565b6040525050565b60006129ce60405190565b90506129da8282612996565b919050565b600067ffffffffffffffff8211156129f9576129f9612980565b5060209081020190565b6000612a16612a11846129df565b6129c3565b83815290506020808201908402830185811115612a3557612a35600080fd5b835b81811015612a5757612a4987826126ee565b835260209283019201612a37565b5050509392505050565b600082601f830112612a7557612a75600080fd5b813561109e848260208601612a03565b6000612a93612a11846129df565b83815290506020808201908402830185811115612ab257612ab2600080fd5b835b81811015612a5757612ac6878261263d565b835260209283019201612ab4565b600082601f830112612ae857612ae8600080fd5b813561109e848260208601612a85565b60008060408385031215612b0e57612b0e600080fd5b823567ffffffffffffffff811115612b2857612b28600080fd5b612b3485828601612a61565b925050602083013567ffffffffffffffff811115612b5457612b54600080fd5b6126b085828601612ad4565b60208101610b0782846128bc565b600060208284031215612b8357612b83600080fd5b600061109e84846127b0565b6001600160c01b038116612623565b60608101612bac82866126ba565b612bb960208301856126ba565b61109e6040830184612b8f565b63ffffffff81166125e8565b8035610b0781612bc6565b600060208284031215612bf257612bf2600080fd5b600061109e8484612bd2565b612c088282612669565b5060200190565b60200190565b6000612c1f825190565b808452602093840193830160005b82811015612c52578151612c418782612bfe565b965050602082019150600101612c2d565b5093949350505050565b602080825281016122ec8184612c15565b60008060408385031215612c8357612c83600080fd5b600061277c85856126ee565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b81810381811115610b0757610b07612ca5565b634e487b7160e01b600052601260045260246000fd5b600082612cf357612cf3612cce565b500690565b80820180821115610b0757610b07612ca5565b600060018201612d1d57612d1d612ca5565b5060010190565b600e8152602081016d24b73b30b634b21031b0b63632b960911b81529050612c0f565b60208082528101610b0781612d24565b8051610b07816126e5565b600060208284031215612d7757612d77600080fd5b600061109e8484612d57565b6000610b0761290e61ffff841681565b61262381612d83565b60e08101612daa828a612669565b612db76020830189612669565b612dc46040830188612669565b612dd16060830187612d93565b612dde6080830186612d93565b612deb60a0830185612d93565b612df860c0830184612669565b98975050505050505050565b8051610b0781612637565b6000612e1d612a11846129df565b83815290506020808201908402830185811115612e3c57612e3c600080fd5b835b81811015612a5757612e508782612e04565b835260209283019201612e3e565b600082601f830112612e7257612e72600080fd5b815161109e848260208601612e0f565b600060208284031215612e9757612e97600080fd5b815167ffffffffffffffff811115612eb157612eb1600080fd5b61109e84828501612e5e565b61ffff918216919081169082820390811115610b0757610b07612ca5565b60208082528101610b0781602f81527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560208201526e103937b632b9903337b91039b2b63360891b604082015260600190565b6001600160c01b03918216919081169082820190811115610b0757610b07612ca5565b6040810161279b82856128bc565b60128152602081017120ba3a30b1b59034b9903737ba1037b832b760711b81529050612c0f565b60208082528101610b0781612f5f565b60408101612fa482856128bc565b6122ec60208301846128bc565b63ffffffff16600063fffffffe198201612d1d57612d1d612ca5565b6001600160a01b031660006002600160a01b03198201612d1d57612d1d612ca5565b60208082527f5061796d656e742073706c69747465722061646472657373206e6f74207365749101908152612c0f565b60208082528101610b0781612fef565b6060810161303d82866128bc565b61273560208301856128bc565b8051610b07816127a8565b60006020828403121561306a5761306a600080fd5b600061109e848461304a565b600d8152602081016c125b9d985b1a59081a5b9c1d5d609a1b81529050612c0f565b60208082528101610b0781613076565b6000602082840312156130bd576130bd600080fd5b600061109e8484612e04565b6015815260208101744d6174683a206d756c446976206f766572666c6f7760581b81529050612c0f565b60208082528101610b07816130c9565b601f8152602081017f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081529050612c0f565b60208082528101610b0781613103565b60005b83811015613160578181015183820152602001613148565b50506000910152565b6000613173825190565b613181818560208601613145565b9290920192915050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526017016131bb8184613169565b7001034b99036b4b9b9b4b733903937b6329607d1b815260110190506122ec8183613169565b60006131eb825190565b808452602084019350613202818560208601613145565b601f01601f19169290920192915050565b602080825281016122ec81846131e1565b8181028115828204841417610b0757610b07612ca5565b60008161324a5761324a612ca5565b506000190190565b60208082527f537472696e67733a20686578206c656e67746820696e73756666696369656e749101908152612c0f565b60208082528101610b078161325256fea49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775a2646970667358221220cd42eedfd7fcf6ee3af4d32ec98c043eb40d0330f0d4c2eecb59e93bdc0f31f964736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001b7d040a501f19f1e28ed9fe58e307a9516ee7330000000000000000000000000000000000000000000000000000000000015180
-----Decoded View---------------
Arg [0] : _configAddress (address): 0x1b7d040A501F19F1e28ed9fe58e307a9516EE733
Arg [1] : _stolenPoolEpochLength (uint32): 86400
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000001b7d040a501f19f1e28ed9fe58e307a9516ee733
Arg [1] : 0000000000000000000000000000000000000000000000000000000000015180
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.