Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- Epoch
- Optimization enabled
- false
- Compiler version
- v0.8.26+commit.8a97fa7a
- EVM Version
- Verified at
- 2026-10-11T05:21:34.118450Z
Constructor Arguments
0000000000000000000000008feb03a1590c041a5ae7d09ff326919129b6f785
Arg [0] (address) : 0x8feb03a1590c041a5ae7d09ff326919129b6f785
contracts/governance/Epoch.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
/// @title Epoch
/// @notice Tracks the protocol lifecycle phase and the router allocation preset for it.
/// @dev Design decision (see docs/architecture.md): transitions are GOVERNANCE-GATED
/// ONLY, never automatic on block number or timestamp. An automatic transition
/// would let the protocol flip its own allocation policy mid-incident with no
/// human in the loop, and the timing would be public and gameable. The
/// PHASE_ADMIN_ROLE is held by the TimelockController, so every transition
/// inherits the timelock delay.
contract Epoch is AccessControl {
bytes32 public constant PHASE_ADMIN_ROLE = keccak256("PHASE_ADMIN_ROLE");
uint16 public constant BPS_DENOMINATOR = 10_000;
enum Phase {
Bootstrapping,
AcceleratedBurn,
GovernanceAndGrowth,
Sustainability
}
struct Allocation {
uint16 pburnBurnBps;
uint16 pflyBurnBps;
uint16 polBps;
uint16 treasuryBps;
}
Phase public currentPhase;
uint64 public phaseStartedAt;
mapping(Phase => Allocation) public presets;
event PhaseChanged(Phase indexed previousPhase, Phase indexed newPhase, uint64 timestamp);
event PresetUpdated(Phase indexed phase, Allocation allocation);
error ZeroAddress();
error AllocationMustTotalDenominator(uint256 provided);
error PhaseNotAdvancing(Phase current, Phase requested);
constructor(address admin) {
if (admin == address(0)) revert ZeroAddress();
_grantRole(DEFAULT_ADMIN_ROLE, admin);
phaseStartedAt = uint64(block.timestamp);
// Bootstrapping: build liquidity and treasury before leaning on burns.
presets[Phase.Bootstrapping] =
Allocation({pburnBurnBps: 2_500, pflyBurnBps: 1_500, polBps: 4_000, treasuryBps: 2_000});
// Accelerated burn: the whitepaper default split, burn-heavy.
presets[Phase.AcceleratedBurn] =
Allocation({pburnBurnBps: 4_000, pflyBurnBps: 4_000, polBps: 1_000, treasuryBps: 1_000});
// Governance and growth: balance burn against reinvestment.
presets[Phase.GovernanceAndGrowth] =
Allocation({pburnBurnBps: 3_000, pflyBurnBps: 2_500, polBps: 2_500, treasuryBps: 2_000});
// Sustainability: prioritise durable treasury and owned liquidity.
presets[Phase.Sustainability] =
Allocation({pburnBurnBps: 2_500, pflyBurnBps: 2_000, polBps: 3_000, treasuryBps: 2_500});
emit PhaseChanged(Phase.Bootstrapping, Phase.Bootstrapping, uint64(block.timestamp));
}
/// @notice Allocation preset for the current phase.
function allocation()
external
view
returns (uint16 pburnBurnBps, uint16 pflyBurnBps, uint16 polBps, uint16 treasuryBps)
{
Allocation memory preset = presets[currentPhase];
return (preset.pburnBurnBps, preset.pflyBurnBps, preset.polBps, preset.treasuryBps);
}
function allocationFor(Phase phase) external view returns (Allocation memory) {
return presets[phase];
}
// --- Governance ---------------------------------------------------------
/// @notice Advance to `newPhase`. Phases only ever move forward.
/// @dev Forward-only prevents a compromised or hasty proposal from rolling the
/// protocol back into bootstrapping parameters after launch.
function advanceTo(Phase newPhase) external onlyRole(PHASE_ADMIN_ROLE) {
Phase previous = currentPhase;
if (uint8(newPhase) <= uint8(previous)) revert PhaseNotAdvancing(previous, newPhase);
currentPhase = newPhase;
phaseStartedAt = uint64(block.timestamp);
emit PhaseChanged(previous, newPhase, uint64(block.timestamp));
}
function setPreset(Phase phase, Allocation calldata newAllocation) external onlyRole(PHASE_ADMIN_ROLE) {
uint256 total = uint256(newAllocation.pburnBurnBps) + newAllocation.pflyBurnBps + newAllocation.polBps
+ newAllocation.treasuryBps;
if (total != BPS_DENOMINATOR) revert AllocationMustTotalDenominator(total);
presets[phase] = newAllocation;
emit PresetUpdated(phase, newAllocation);
}
}
lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* 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[ERC 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);
}
lib/openzeppelin-contracts/contracts/access/AccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)
pragma solidity ^0.8.20;
import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {ERC165} from "../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 account => bool) hasRole;
bytes32 adminRole;
}
mapping(bytes32 role => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with an {AccessControlUnauthorizedAccount} error including the required role.
*/
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 returns (bool) {
return _roles[role].hasRole[account];
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
* is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
* is missing `role`.
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert AccessControlUnauthorizedAccount(account, role);
}
}
/**
* @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 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 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 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 `callerConfirmation`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
/**
* @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 Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
if (!hasRole(role, account)) {
_roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
/**
* @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
if (hasRole(role, account)) {
_roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
}
lib/openzeppelin-contracts/contracts/access/IAccessControl.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (access/IAccessControl.sol)
pragma solidity ^0.8.20;
/**
* @dev External interface of AccessControl declared to support ERC-165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @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.
*/
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. This account bears the admin role (for the granted role).
* Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.
*/
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 `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
}
lib/openzeppelin-contracts/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @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;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC-165 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);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
Compiler Settings
{"viaIR":false,"remappings":["@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/","forge-std/=lib/forge-std/src/","ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/","erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/","openzeppelin-contracts/=lib/openzeppelin-contracts/"],"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode"]}},"optimizer":{"runs":200,"enabled":true},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"paris"}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"admin","internalType":"address"}]},{"type":"error","name":"AccessControlBadConfirmation","inputs":[]},{"type":"error","name":"AccessControlUnauthorizedAccount","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"bytes32","name":"neededRole","internalType":"bytes32"}]},{"type":"error","name":"AllocationMustTotalDenominator","inputs":[{"type":"uint256","name":"provided","internalType":"uint256"}]},{"type":"error","name":"PhaseNotAdvancing","inputs":[{"type":"uint8","name":"current","internalType":"enum Epoch.Phase"},{"type":"uint8","name":"requested","internalType":"enum Epoch.Phase"}]},{"type":"error","name":"ZeroAddress","inputs":[]},{"type":"event","name":"PhaseChanged","inputs":[{"type":"uint8","name":"previousPhase","internalType":"enum Epoch.Phase","indexed":true},{"type":"uint8","name":"newPhase","internalType":"enum Epoch.Phase","indexed":true},{"type":"uint64","name":"timestamp","internalType":"uint64","indexed":false}],"anonymous":false},{"type":"event","name":"PresetUpdated","inputs":[{"type":"uint8","name":"phase","internalType":"enum Epoch.Phase","indexed":true},{"type":"tuple","name":"allocation","internalType":"struct Epoch.Allocation","indexed":false,"components":[{"type":"uint16","name":"pburnBurnBps","internalType":"uint16"},{"type":"uint16","name":"pflyBurnBps","internalType":"uint16"},{"type":"uint16","name":"polBps","internalType":"uint16"},{"type":"uint16","name":"treasuryBps","internalType":"uint16"}]}],"anonymous":false},{"type":"event","name":"RoleAdminChanged","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"previousAdminRole","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"newAdminRole","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"RoleGranted","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32","indexed":true},{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"address","name":"sender","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RoleRevoked","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32","indexed":true},{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"address","name":"sender","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"BPS_DENOMINATOR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"DEFAULT_ADMIN_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"PHASE_ADMIN_ROLE","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"advanceTo","inputs":[{"type":"uint8","name":"newPhase","internalType":"enum Epoch.Phase"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"pburnBurnBps","internalType":"uint16"},{"type":"uint16","name":"pflyBurnBps","internalType":"uint16"},{"type":"uint16","name":"polBps","internalType":"uint16"},{"type":"uint16","name":"treasuryBps","internalType":"uint16"}],"name":"allocation","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct Epoch.Allocation","components":[{"type":"uint16","name":"pburnBurnBps","internalType":"uint16"},{"type":"uint16","name":"pflyBurnBps","internalType":"uint16"},{"type":"uint16","name":"polBps","internalType":"uint16"},{"type":"uint16","name":"treasuryBps","internalType":"uint16"}]}],"name":"allocationFor","inputs":[{"type":"uint8","name":"phase","internalType":"enum Epoch.Phase"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"enum Epoch.Phase"}],"name":"currentPhase","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getRoleAdmin","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"grantRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"hasRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"phaseStartedAt","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"pburnBurnBps","internalType":"uint16"},{"type":"uint16","name":"pflyBurnBps","internalType":"uint16"},{"type":"uint16","name":"polBps","internalType":"uint16"},{"type":"uint16","name":"treasuryBps","internalType":"uint16"}],"name":"presets","inputs":[{"type":"uint8","name":"","internalType":"enum Epoch.Phase"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"callerConfirmation","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revokeRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPreset","inputs":[{"type":"uint8","name":"phase","internalType":"enum Epoch.Phase"},{"type":"tuple","name":"newAllocation","internalType":"struct Epoch.Allocation","components":[{"type":"uint16","name":"pburnBurnBps","internalType":"uint16"},{"type":"uint16","name":"pflyBurnBps","internalType":"uint16"},{"type":"uint16","name":"polBps","internalType":"uint16"},{"type":"uint16","name":"treasuryBps","internalType":"uint16"}]}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"interfaceId","internalType":"bytes4"}]}]
Contract Creation Code
0x608060405234801561001057600080fd5b5060405161109338038061109383398101604081905261002f91610428565b6001600160a01b0381166100565760405163d92e233d60e01b815260040160405180910390fd5b61006160008261037c565b5060018054610100600160481b031916610100426001600160401b03160217815560408051608080820183526109c482526105dc6020808401918252610fa08486018181526107d060608088019182526000808052600280875298517fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b805498519551945161ffff90811666010000000000000261ffff60301b19968216640100000000029690961663ffffffff60201b19978216620100000263ffffffff19909b1691909316179890981794909416939093179190911790945586519485018752818552918401526103e8948301859052908201939093529290919081526020808201929092526040908101600090812084518154868601518786015160609889015161ffff90811666010000000000000261ffff60301b19928216640100000000029290921663ffffffff60201b19938216620100000263ffffffff1990951691909516179290921716919091171790558151608081018352610bb881526109c4938101849052918201929092526107d09281019290925260029081600381111561021057610210610458565b81526020808201929092526040908101600090812084518154868601518786015160609889015161ffff90811666010000000000000261ffff60301b19928216640100000000029290921663ffffffff60201b19938216620100000263ffffffff19909516919095161792909217169190911717905581516080810183526109c48082526107d094820194909452610bb89281019290925292810191909152906002906003808111156102c5576102c5610458565b81526020808201929092526040908101600090812084518154868601518786015160609098015161ffff90811666010000000000000261ffff60301b19998216640100000000029990991663ffffffff60201b19928216620100000263ffffffff1990941691909416179190911716179490941790935580516001600160401b0342168152905183927fbb0570f5e141db4f053495b1ca81eb479df57d853003d5a45b87fcdff9aef097928290030190a35061046e565b6000828152602081815260408083206001600160a01b038516845290915281205460ff1661041e576000838152602081815260408083206001600160a01b03861684529091529020805460ff191660011790556103d63390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610422565b5060005b92915050565b60006020828403121561043a57600080fd5b81516001600160a01b038116811461045157600080fd5b9392505050565b634e487b7160e01b600052602160045260246000fd5b610c168061047d6000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c8063a217fddf11610097578063d547741f11610066578063d547741f146102c9578063da91f50f146102dc578063e1a45218146102ef578063f5d1265f1461030b57600080fd5b8063a217fddf146101fc578063ad71f49314610204578063b1d3873214610247578063b7496a40146102a257600080fd5b80632f2ff15d116100d35780632f2ff15d1461018d57806336568abe146101a057806388a17bde146101b357806391d14854146101e957600080fd5b806301ffc9a714610105578063055ad42e1461012d5780630cdffb0c14610147578063248a9ca31461015c575b600080fd5b610118610113366004610931565b61033d565b60405190151581526020015b60405180910390f35b60015461013a9060ff1681565b604051610124919061099a565b61015a6101553660046109bc565b610374565b005b61017f61016a3660046109fb565b60009081526020819052604090206001015490565b604051908152602001610124565b61015a61019b366004610a14565b6104cb565b61015a6101ae366004610a14565b6104f6565b6101bb61052e565b6040805161ffff95861681529385166020850152918416918301919091529091166060820152608001610124565b6101186101f7366004610a14565b6105cf565b61017f600081565b6101bb610212366004610a50565b60026020526000908152604090205461ffff808216916201000081048216916401000000008204811691600160301b90041684565b61025a610255366004610a50565b6105f8565b6040516101249190600060808201905061ffff835116825261ffff602084015116602083015261ffff604084015116604083015261ffff606084015116606083015292915050565b61017f7f7dca26d7d97207412d34657a97051ab13fab9350eb99a7cd6457ccbfdf20ebad81565b61015a6102d7366004610a14565b61069e565b61015a6102ea366004610a50565b6106c3565b6102f861271081565b60405161ffff9091168152602001610124565b60015461032490610100900467ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610124565b60006001600160e01b03198216637965db0b60e01b148061036e57506301ffc9a760e01b6001600160e01b03198316145b92915050565b7f7dca26d7d97207412d34657a97051ab13fab9350eb99a7cd6457ccbfdf20ebad61039e816107ea565b60006103b06080840160608501610a7b565b61ffff166103c46060850160408601610a7b565b61ffff166103d86040860160208701610a7b565b61ffff166103e96020870187610a7b565b61ffff166103f79190610a98565b6104019190610a98565b61040b9190610a98565b90506127108114610437576040516309a1b40560e11b8152600481018290526024015b60405180910390fd5b826002600086600381111561044e5761044e610962565b600381111561045f5761045f610962565b815260200190815260200160002081816104799190610ab9565b90505083600381111561048e5761048e610962565b7f3a8d94459e15b1dcda7e48a0b6bccff04bc309594f8440b77e6a66caecdef12f846040516104bd9190610b63565b60405180910390a250505050565b6000828152602081905260409020600101546104e6816107ea565b6104f083836107f7565b50505050565b6001600160a01b038116331461051f5760405163334bd91960e11b815260040160405180910390fd5b6105298282610889565b505050565b600080600080600060026000600160009054906101000a900460ff16600381111561055b5761055b610962565b600381111561056c5761056c610962565b815260208082019290925260409081016000208151608081018352905461ffff808216808452620100008304821695840186905264010000000083048216948401859052600160301b909204166060909201829052989297509095509350915050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6040805160808101825260008082526020820181905291810182905260608101919091526002600083600381111561063257610632610962565b600381111561064357610643610962565b815260208082019290925260409081016000208151608081018352905461ffff80821683526201000082048116948301949094526401000000008104841692820192909252600160301b909104909116606082015292915050565b6000828152602081905260409020600101546106b9816107ea565b6104f08383610889565b7f7dca26d7d97207412d34657a97051ab13fab9350eb99a7cd6457ccbfdf20ebad6106ed816107ea565b60015460ff1680600381111561070557610705610962565b60ff1683600381111561071a5761071a610962565b60ff161161073f57808360405163a4d413df60e01b815260040161042e929190610bc5565b6001805484919060ff19168183600381111561075d5761075d610962565b02179055506001805468ffffffffffffffff0019166101004267ffffffffffffffff160217905582600381111561079657610796610962565b8160038111156107a8576107a8610962565b60405167ffffffffffffffff421681527fbb0570f5e141db4f053495b1ca81eb479df57d853003d5a45b87fcdff9aef0979060200160405180910390a3505050565b6107f481336108f4565b50565b600061080383836105cf565b610881576000838152602081815260408083206001600160a01b03861684529091529020805460ff191660011790556108393390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161036e565b50600061036e565b600061089583836105cf565b15610881576000838152602081815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a450600161036e565b6108fe82826105cf565b61092d5760405163e2517d3f60e01b81526001600160a01b03821660048201526024810183905260440161042e565b5050565b60006020828403121561094357600080fd5b81356001600160e01b03198116811461095b57600080fd5b9392505050565b634e487b7160e01b600052602160045260246000fd5b6004811061099657634e487b7160e01b600052602160045260246000fd5b9052565b6020810161036e8284610978565b8035600481106109b757600080fd5b919050565b60008082840360a08112156109d057600080fd5b6109d9846109a8565b92506080601f19820112156109ed57600080fd5b506020830190509250929050565b600060208284031215610a0d57600080fd5b5035919050565b60008060408385031215610a2757600080fd5b8235915060208301356001600160a01b0381168114610a4557600080fd5b809150509250929050565b600060208284031215610a6257600080fd5b61095b826109a8565b61ffff811681146107f457600080fd5b600060208284031215610a8d57600080fd5b813561095b81610a6b565b8082018082111561036e57634e487b7160e01b600052601160045260246000fd5b8135610ac481610a6b565b61ffff8116905081548161ffff1982161783556020840135610ae581610a6b565b63ffff00008160101b169050808363ffffffff198416171784556040850135610b0d81610a6b565b65ffff000000008160201b168465ffffffffffff1985161783171785555050505060006060830135610b3e81610a6b565b825467ffff000000000000191660309190911b67ffff00000000000016179091555050565b608081018235610b7281610a6b565b61ffff1682526020830135610b8681610a6b565b61ffff1660208301526040830135610b9d81610a6b565b61ffff1660408301526060830135610bb481610a6b565b61ffff811660608401525092915050565b60408101610bd38285610978565b61095b602083018461097856fea2646970667358221220a89aa83b4bfa77876db420e0363a747036da2cdb488e7e6af235aa08eabaf84664736f6c634300081a00330000000000000000000000008feb03a1590c041a5ae7d09ff326919129b6f785
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106101005760003560e01c8063a217fddf11610097578063d547741f11610066578063d547741f146102c9578063da91f50f146102dc578063e1a45218146102ef578063f5d1265f1461030b57600080fd5b8063a217fddf146101fc578063ad71f49314610204578063b1d3873214610247578063b7496a40146102a257600080fd5b80632f2ff15d116100d35780632f2ff15d1461018d57806336568abe146101a057806388a17bde146101b357806391d14854146101e957600080fd5b806301ffc9a714610105578063055ad42e1461012d5780630cdffb0c14610147578063248a9ca31461015c575b600080fd5b610118610113366004610931565b61033d565b60405190151581526020015b60405180910390f35b60015461013a9060ff1681565b604051610124919061099a565b61015a6101553660046109bc565b610374565b005b61017f61016a3660046109fb565b60009081526020819052604090206001015490565b604051908152602001610124565b61015a61019b366004610a14565b6104cb565b61015a6101ae366004610a14565b6104f6565b6101bb61052e565b6040805161ffff95861681529385166020850152918416918301919091529091166060820152608001610124565b6101186101f7366004610a14565b6105cf565b61017f600081565b6101bb610212366004610a50565b60026020526000908152604090205461ffff808216916201000081048216916401000000008204811691600160301b90041684565b61025a610255366004610a50565b6105f8565b6040516101249190600060808201905061ffff835116825261ffff602084015116602083015261ffff604084015116604083015261ffff606084015116606083015292915050565b61017f7f7dca26d7d97207412d34657a97051ab13fab9350eb99a7cd6457ccbfdf20ebad81565b61015a6102d7366004610a14565b61069e565b61015a6102ea366004610a50565b6106c3565b6102f861271081565b60405161ffff9091168152602001610124565b60015461032490610100900467ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610124565b60006001600160e01b03198216637965db0b60e01b148061036e57506301ffc9a760e01b6001600160e01b03198316145b92915050565b7f7dca26d7d97207412d34657a97051ab13fab9350eb99a7cd6457ccbfdf20ebad61039e816107ea565b60006103b06080840160608501610a7b565b61ffff166103c46060850160408601610a7b565b61ffff166103d86040860160208701610a7b565b61ffff166103e96020870187610a7b565b61ffff166103f79190610a98565b6104019190610a98565b61040b9190610a98565b90506127108114610437576040516309a1b40560e11b8152600481018290526024015b60405180910390fd5b826002600086600381111561044e5761044e610962565b600381111561045f5761045f610962565b815260200190815260200160002081816104799190610ab9565b90505083600381111561048e5761048e610962565b7f3a8d94459e15b1dcda7e48a0b6bccff04bc309594f8440b77e6a66caecdef12f846040516104bd9190610b63565b60405180910390a250505050565b6000828152602081905260409020600101546104e6816107ea565b6104f083836107f7565b50505050565b6001600160a01b038116331461051f5760405163334bd91960e11b815260040160405180910390fd5b6105298282610889565b505050565b600080600080600060026000600160009054906101000a900460ff16600381111561055b5761055b610962565b600381111561056c5761056c610962565b815260208082019290925260409081016000208151608081018352905461ffff808216808452620100008304821695840186905264010000000083048216948401859052600160301b909204166060909201829052989297509095509350915050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6040805160808101825260008082526020820181905291810182905260608101919091526002600083600381111561063257610632610962565b600381111561064357610643610962565b815260208082019290925260409081016000208151608081018352905461ffff80821683526201000082048116948301949094526401000000008104841692820192909252600160301b909104909116606082015292915050565b6000828152602081905260409020600101546106b9816107ea565b6104f08383610889565b7f7dca26d7d97207412d34657a97051ab13fab9350eb99a7cd6457ccbfdf20ebad6106ed816107ea565b60015460ff1680600381111561070557610705610962565b60ff1683600381111561071a5761071a610962565b60ff161161073f57808360405163a4d413df60e01b815260040161042e929190610bc5565b6001805484919060ff19168183600381111561075d5761075d610962565b02179055506001805468ffffffffffffffff0019166101004267ffffffffffffffff160217905582600381111561079657610796610962565b8160038111156107a8576107a8610962565b60405167ffffffffffffffff421681527fbb0570f5e141db4f053495b1ca81eb479df57d853003d5a45b87fcdff9aef0979060200160405180910390a3505050565b6107f481336108f4565b50565b600061080383836105cf565b610881576000838152602081815260408083206001600160a01b03861684529091529020805460ff191660011790556108393390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600161036e565b50600061036e565b600061089583836105cf565b15610881576000838152602081815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a450600161036e565b6108fe82826105cf565b61092d5760405163e2517d3f60e01b81526001600160a01b03821660048201526024810183905260440161042e565b5050565b60006020828403121561094357600080fd5b81356001600160e01b03198116811461095b57600080fd5b9392505050565b634e487b7160e01b600052602160045260246000fd5b6004811061099657634e487b7160e01b600052602160045260246000fd5b9052565b6020810161036e8284610978565b8035600481106109b757600080fd5b919050565b60008082840360a08112156109d057600080fd5b6109d9846109a8565b92506080601f19820112156109ed57600080fd5b506020830190509250929050565b600060208284031215610a0d57600080fd5b5035919050565b60008060408385031215610a2757600080fd5b8235915060208301356001600160a01b0381168114610a4557600080fd5b809150509250929050565b600060208284031215610a6257600080fd5b61095b826109a8565b61ffff811681146107f457600080fd5b600060208284031215610a8d57600080fd5b813561095b81610a6b565b8082018082111561036e57634e487b7160e01b600052601160045260246000fd5b8135610ac481610a6b565b61ffff8116905081548161ffff1982161783556020840135610ae581610a6b565b63ffff00008160101b169050808363ffffffff198416171784556040850135610b0d81610a6b565b65ffff000000008160201b168465ffffffffffff1985161783171785555050505060006060830135610b3e81610a6b565b825467ffff000000000000191660309190911b67ffff00000000000016179091555050565b608081018235610b7281610a6b565b61ffff1682526020830135610b8681610a6b565b61ffff1660208301526040830135610b9d81610a6b565b61ffff1660408301526060830135610bb481610a6b565b61ffff811660608401525092915050565b60408101610bd38285610978565b61095b602083018461097856fea2646970667358221220a89aa83b4bfa77876db420e0363a747036da2cdb488e7e6af235aa08eabaf84664736f6c634300081a0033