Overview
Max Total Supply
346,280,081.256296972070689693 xREX
Holders
1,576
Market
Price
$0.00 @ 0.000000 ETH
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
304,275,157.358332447718568393 xREXValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
Contract Name:
XRex
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {IVoter} from "../interfaces/IVoter.sol";
import {IXRex} from "../interfaces/IXRex.sol";
import {Errors} from "contracts/libraries/Errors.sol";
import {IVoteModule} from "../interfaces/IVoteModule.sol";
/// @title xREX contract for Etherex
/// @dev Staked version of REX that allows for PvP rebase and voting
contract XRex is ERC20, IXRex, Pausable {
using EnumerableSet for EnumerableSet.AddressSet;
/**
* Addresses
*/
/// @inheritdoc IXRex
address public operator;
/// @inheritdoc IXRex
address public immutable MINTER;
/// @inheritdoc IXRex
address public immutable ACCESS_HUB;
/// @inheritdoc IXRex
address public immutable VOTE_MODULE;
/// @dev IERC20 declaration of REX
IERC20 public immutable REX;
/// @dev declare IVoter
IVoter public immutable VOTER;
/// @inheritdoc IXRex
uint256 public constant BASIS = 1_000_000;
/// @inheritdoc IXRex
uint256 public constant SLASHING_PENALTY = 500_000;
/// @dev stores the addresses that are exempt from transfer limitations when transferring out
EnumerableSet.AddressSet exempt;
/// @dev stores the addresses that are exempt from transfer limitations when transferring to them
EnumerableSet.AddressSet exemptTo;
/// @inheritdoc IXRex
uint256 public lastDistributedPeriod;
/// @inheritdoc IXRex
uint256 public pendingRebase;
/// @inheritdoc IXRex
uint256 public rebaseThreshold;
modifier onlyGovernance() {
require(msg.sender == ACCESS_HUB, Errors.NOT_AUTHORIZED(msg.sender));
_;
}
constructor(
address _rex,
address _voter,
address _operator,
address _accessHub,
address _voteModule,
address _minter
) ERC20("xREX", "xREX") {
REX = IERC20(_rex);
VOTER = IVoter(_voter);
MINTER = _minter;
operator = _operator;
ACCESS_HUB = _accessHub;
VOTE_MODULE = _voteModule;
/// @dev exempt voter, operator, and the vote module
exempt.add(_voter);
exempt.add(operator);
exempt.add(VOTE_MODULE);
exemptTo.add(VOTE_MODULE);
/// @dev grab current period from voter
lastDistributedPeriod = IVoter(_voter).getPeriod();
rebaseThreshold = 1e18;
emit NewRebaseThreshold(1e18);
}
/// @inheritdoc IXRex
function pause() external onlyGovernance {
_pause();
}
/// @inheritdoc IXRex
function unpause() external onlyGovernance {
_unpause();
}
/**
*
*/
// ERC20 Overrides and Helpers
/**
*
*/
function _update(address from, address to, uint256 value) internal override {
/* cases we account for:
*
* minting and burning
* if the "to" is part of the special exemptions
* withdraw and deposit calls
* if "from" is a gauge or feeDist
*
*/
uint8 _u;
if (_isExempted(from, to)) {
_u = 1;
} else if (VOTER.isGauge(from) || VOTER.isFeeDistributor(from)) {
/// @dev add to the exempt set
exempt.add(from);
_u = 1;
}
/// @dev if all previous checks are passed
require(_u == 1, Errors.NOT_WHITELISTED(from));
/// @dev call parent function
super._update(from, to, value);
}
/// @dev internal check for the transfer whitelist
function _isExempted(address _from, address _to) internal view returns (bool) {
return (exempt.contains(_from) || _from == address(0) || _to == address(0) || exemptTo.contains(_to));
}
/**
*
*/
// General use functions
/**
*
*/
/// @inheritdoc IXRex
function convertEmissionsToken(uint256 _amount) external whenNotPaused {
/// @dev ensure the _amount is > 0
require(_amount != 0, Errors.ZERO());
/// @dev transfer from the caller to this address
REX.transferFrom(msg.sender, address(this), _amount);
/// @dev mint the xREX to the caller
_mint(msg.sender, _amount);
/// @dev emit an event for conversion
emit Converted(msg.sender, _amount);
}
/// @inheritdoc IXRex
function rebase() external whenNotPaused {
/// @dev gate to minter and call it on epoch flips
require(msg.sender == MINTER, Errors.NOT_AUTHORIZED(msg.sender));
/// @dev fetch the current period
uint256 period = VOTER.getPeriod();
/// @dev if it's a new period (epoch)
if (
/// @dev if the rebase is greater than the rebaseThreshold
period > lastDistributedPeriod && pendingRebase >= rebaseThreshold
) {
/// @dev PvP rebase notified to the voteModule staking contract to stream to xREX after epoch flips
/// @dev fetch the current period from voter
lastDistributedPeriod = period;
/// @dev store the rebase
uint256 _temp = pendingRebase;
/// @dev zero it out before sending
pendingRebase = 0;
/// @dev approve REX transferring to voteModule
REX.approve(VOTE_MODULE, _temp);
/// @dev notify the REX rebase
IVoteModule(VOTE_MODULE).notifyRewardAmount(_temp);
emit Rebase(msg.sender, _temp);
}
}
/// @inheritdoc IXRex
function exit(uint256 _amount) external whenNotPaused returns (uint256 _exitedAmount) {
/// @dev cannot exit a 0 amount
require(_amount != 0, Errors.ZERO());
/// @dev if it's at least 2 wei it will give a penalty
uint256 penalty = ((_amount * SLASHING_PENALTY) / BASIS);
uint256 exitAmount = _amount - penalty;
/// @dev burn the xREX from the caller's address
_burn(msg.sender, _amount);
/// @dev store the rebase earned from the penalty
pendingRebase += penalty;
/// @dev transfer the exitAmount to the caller
REX.transfer(msg.sender, exitAmount);
/// @dev emit actual exited amount
emit InstantExit(msg.sender, exitAmount);
return exitAmount;
}
/**
*
*/
// Permissioned functions, timelock/operator gated
/**
*
*/
/// @inheritdoc IXRex
function operatorRedeem(uint256 _amount) external onlyGovernance {
_burn(operator, _amount);
REX.transfer(operator, _amount);
emit XRamRedeemed(address(this), _amount);
}
/// @inheritdoc IXRex
function rescueTrappedTokens(address[] calldata _tokens, uint256[] calldata _amounts) external onlyGovernance {
for (uint256 i = 0; i < _tokens.length; ++i) {
/// @dev cant fetch the underlying
require(_tokens[i] != address(REX), Errors.CANT_RESCUE());
IERC20(_tokens[i]).transfer(operator, _amounts[i]);
}
}
/// @inheritdoc IXRex
function migrateOperator(address _operator) external onlyGovernance {
/// @dev ensure operator is different
require(operator != _operator, Errors.NO_CHANGE());
emit NewOperator(operator, _operator);
operator = _operator;
}
/// @inheritdoc IXRex
function setExemption(address[] calldata _exemptee, bool[] calldata _exempt) external onlyGovernance {
/// @dev ensure arrays of same length
require(_exemptee.length == _exempt.length, Errors.ARRAY_LENGTHS());
/// @dev loop through all and attempt add/remove based on status
for (uint256 i = 0; i < _exempt.length; ++i) {
bool success = _exempt[i] ? exempt.add(_exemptee[i]) : exempt.remove(_exemptee[i]);
/// @dev emit : (who, status, success)
emit Exemption(_exemptee[i], _exempt[i], success);
}
}
/// @inheritdoc IXRex
function setExemptionTo(address[] calldata _exemptee, bool[] calldata _exempt) external onlyGovernance {
/// @dev ensure arrays of same length
require(_exemptee.length == _exempt.length, Errors.ARRAY_LENGTHS());
/// @dev loop through all and attempt add/remove based on status
for (uint256 i = 0; i < _exempt.length; ++i) {
bool success = _exempt[i] ? exemptTo.add(_exemptee[i]) : exemptTo.remove(_exemptee[i]);
/// @dev emit : (who, status, success)
emit Exemption(_exemptee[i], _exempt[i], success);
}
}
/// @inheritdoc IXRex
function setRebaseThreshold(uint256 _newThreshold) external onlyGovernance {
if (rebaseThreshold != _newThreshold) {
rebaseThreshold = _newThreshold;
emit NewRebaseThreshold(_newThreshold);
}
}
/**
*
*/
// Getter functions
/**
*
*/
/// @inheritdoc IXRex
function getBalanceResiding() public view returns (uint256 _amount) {
/// @dev simply returns the balance of the underlying
return REX.balanceOf(address(this));
}
/// @inheritdoc IXRex
function isExempt(address _who) external view returns (bool _exempt) {
return exempt.contains(_who);
}
/// @inheritdoc IXRex
function isExemptTo(address _who) external view returns (bool _exempt) {
return exemptTo.contains(_who);
}
/// @inheritdoc IXRex
function rex() external view returns (address) {
return address(REX);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC-20
* applications.
*/
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
mapping(address account => uint256) private _balances;
mapping(address account => mapping(address spender => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `value`.
*/
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Skips emitting an {Approval} event indicating an allowance update. This is not
* required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `value`.
* - the caller must have allowance for ``from``'s tokens of at least
* `value`.
*/
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
/**
* @dev Moves a `value` amount of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(from, to, value);
}
/**
* @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
* (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
* this function.
*
* Emits a {Transfer} event.
*/
function _update(address from, address to, uint256 value) internal virtual {
if (from == address(0)) {
// Overflow check required: The rest of the code assumes that totalSupply never overflows
_totalSupply += value;
} else {
uint256 fromBalance = _balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
// Overflow not possible: value <= fromBalance <= totalSupply.
_balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
_totalSupply -= value;
}
} else {
unchecked {
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
_balances[to] += value;
}
}
emit Transfer(from, to, value);
}
/**
* @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
* Relies on the `_update` mechanism
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
/**
* @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
* Relies on the `_update` mechanism.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead
*/
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
/**
* @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
/**
* @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
*
* By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
* `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
* `Approval` event during `transferFrom` operations.
*
* Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
* true using the following override:
*
* ```solidity
* function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
* super._approve(owner, spender, value, true);
* }
* ```
*
* Requirements are the same as {_approve}.
*/
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
_allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `value`.
*
* Does not update the allowance value in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Does not emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
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 value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` 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 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
bool private _paused;
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
/**
* @dev The operation failed because the contract is paused.
*/
error EnforcedPause();
/**
* @dev The operation failed because the contract is not paused.
*/
error ExpectedPause();
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
if (paused()) {
revert EnforcedPause();
}
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
if (!paused()) {
revert ExpectedPause();
}
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
pragma solidity ^0.8.20;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```solidity
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableSet.
* ====
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position is the index of the value in the `values` array plus 1.
// Position 0 is used to mean a value is not in the set.
mapping(bytes32 value => uint256) _positions;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._positions[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We cache the value's position to prevent multiple reads from the same storage slot
uint256 position = set._positions[value];
if (position != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 valueIndex = position - 1;
uint256 lastIndex = set._values.length - 1;
if (valueIndex != lastIndex) {
bytes32 lastValue = set._values[lastIndex];
// Move the lastValue to the index where the value to delete is
set._values[valueIndex] = lastValue;
// Update the tracked position of the lastValue (that was just moved)
set._positions[lastValue] = position;
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the tracked position for the deleted slot
delete set._positions[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._positions[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
pragma abicoder v2;
interface IVoter {
event GaugeCreated(address indexed gauge, address creator, address feeDistributor, address indexed pool);
event GaugeKilled(address indexed gauge);
event GaugeRevived(address indexed gauge);
event Voted(address indexed owner, uint256 weight, address indexed pool);
event Abstained(address indexed owner, uint256 weight);
event Deposit(address indexed lp, address indexed gauge, address indexed owner, uint256 amount);
event Withdraw(address indexed lp, address indexed gauge, address indexed owner, uint256 amount);
event NotifyReward(address indexed sender, address indexed reward, uint256 amount);
event DistributeReward(address indexed sender, address indexed gauge, uint256 amount);
event EmissionsRatio(address indexed caller, uint256 oldRatio, uint256 newRatio);
event NewGovernor(address indexed sender, address indexed governor);
event Whitelisted(address indexed whitelister, address indexed token);
event WhitelistRevoked(address indexed forbidder, address indexed token, bool status);
event Poke(address indexed user);
event EmissionsRedirected(address indexed sourceGauge, address indexed destinationGauge);
struct InitializationParams {
address ram;
address legacyFactory;
address gauges;
address feeDistributorFactory;
address minter;
address msig;
address xRam;
address clFactory;
address clGaugeFactory;
address nfpManager;
address feeRecipientFactory;
address voteModule;
}
function initialize(InitializationParams memory inputs) external;
/// @notice denominator basis
function BASIS() external view returns (uint256);
/// @notice ratio of xRam emissions globally
function xRatio() external view returns (uint256);
/// @notice minimum time threshold for rewarder (in seconds)
function timeThresholdForRewarder() external view returns (uint256);
/// @notice xRam contract address
function xRam() external view returns (address);
/// @notice legacy factory address (uni-v2/stableswap)
function legacyFactory() external view returns (address);
/// @notice concentrated liquidity factory
function clFactory() external view returns (address);
/// @notice gauge factory for CL
function clGaugeFactory() external view returns (address);
/// @notice legacy fee recipient factory
function feeRecipientFactory() external view returns (address);
/// @notice peripheral NFPManager contract
function nfpManager() external view returns (address);
/// @notice returns the address of the current governor
/// @return _governor address of the governor
function governor() external view returns (address _governor);
/// @notice the address of the vote module
/// @return _voteModule the vote module contract address
function voteModule() external view returns (address _voteModule);
/// @notice address of the central access Hub
function accessHub() external view returns (address);
/// @notice distributes emissions from the minter to the voter
/// @param amount the amount of tokens to notify
function notifyRewardAmount(uint256 amount) external;
/// @notice distributes the emissions for a specific gauge
/// @param _gauge the gauge address
function distribute(address _gauge) external;
/// @notice returns the address of the gauge factory
/// @param _gaugeFactory gauge factory address
function gaugeFactory() external view returns (address _gaugeFactory);
/// @notice returns the address of the feeDistributor factory
/// @return _feeDistributorFactory feeDist factory address
function feeDistributorFactory() external view returns (address _feeDistributorFactory);
/// @notice returns the address of the minter contract
/// @return _minter address of the minter
function minter() external view returns (address _minter);
/// @notice check if the gauge is active for governance use
/// @param _gauge address of the gauge
/// @return _trueOrFalse if the gauge is alive
function isAlive(address _gauge) external view returns (bool _trueOrFalse);
/// @notice allows the token to be paired with other whitelisted assets to participate in governance
/// @param _token the address of the token
function whitelist(address _token) external;
/// @notice effectively disqualifies a token from governance
/// @param _token the address of the token
function revokeWhitelist(address _token) external;
/// @notice returns if the address is a gauge
/// @param gauge address of the gauge
/// @return _trueOrFalse boolean if the address is a gauge
function isGauge(address gauge) external view returns (bool _trueOrFalse);
/// @notice disable a gauge from governance
/// @param _gauge address of the gauge
function killGauge(address _gauge) external;
/// @notice re-activate a dead gauge
/// @param _gauge address of the gauge
function reviveGauge(address _gauge) external;
/// @notice re-cast a tokenID's votes
/// @param owner address of the owner
function poke(address owner) external;
/// @notice sets the main destinationGauge of a token pairing
/// @param tokenA address of tokenA
/// @param tokenB address of tokenB
/// @param destinationGauge the main gauge to set to
function redirectEmissions(address tokenA, address tokenB, address destinationGauge) external;
/// @notice returns if the address is a fee distributor
/// @param _feeDistributor address of the feeDist
/// @return _trueOrFalse if the address is a fee distributor
function isFeeDistributor(address _feeDistributor) external view returns (bool _trueOrFalse);
/// @notice returns the address of the emission's token
/// @return _ram emissions token contract address
function ram() external view returns (address _ram);
/// @notice returns the address of the pool's gauge, if any
/// @param _pool pool address
/// @return _gauge gauge address
function gaugeForPool(address _pool) external view returns (address _gauge);
/// @notice returns the address of the pool's feeDistributor, if any
/// @param _gauge address of the gauge
/// @return _feeDistributor address of the pool's feedist
function feeDistributorForGauge(address _gauge) external view returns (address _feeDistributor);
/// @notice returns the gauge address of a CL pool
/// @param tokenA address of token A in the pair
/// @param tokenB address of token B in the pair
/// @param tickSpacing tickspacing of the pool
/// @return gauge address of the gauge
function gaugeForClPool(address tokenA, address tokenB, int24 tickSpacing) external view returns (address gauge);
/// @notice returns the array of all tickspacings for the tokenA/tokenB combination
/// @param tokenA address of token A in the pair
/// @param tokenB address of token B in the pair
/// @return _ts array of all the tickspacings
function tickSpacingsForPair(address tokenA, address tokenB) external view returns (int24[] memory _ts);
/// @notice returns the destination of a gauge redirect
/// @param gauge address of gauge
function gaugeRedirect(address gauge) external view returns (address);
/// @notice returns the block.timestamp divided by 1 week in seconds
/// @return period the period used for gauges
function getPeriod() external view returns (uint256 period);
/// @notice cast a vote to direct emissions to gauges and earn incentives
/// @param owner address of the owner
/// @param _pools the list of pools to vote on
/// @param _weights an arbitrary weight per pool which will be normalized to 100% regardless of numerical inputs
function vote(address owner, address[] calldata _pools, uint256[] calldata _weights) external;
/// @notice reset the vote of an address
/// @param owner address of the owner
function reset(address owner) external;
/// @notice set the governor address
/// @param _governor the new governor address
function setGovernor(address _governor) external;
/// @notice recover stuck emissions
/// @param _gauge the gauge address
/// @param _period the period
function stuckEmissionsRecovery(address _gauge, uint256 _period) external;
/// @notice creates a legacy gauge for the pool
/// @param _pool pool's address
/// @return _gauge address of the new gauge
function createGauge(address _pool) external returns (address _gauge);
/// @notice create a concentrated liquidity gauge
/// @param tokenA the address of tokenA
/// @param tokenB the address of tokenB
/// @param tickSpacing the tickspacing of the pool
/// @return _clGauge address of the new gauge
function createCLGauge(address tokenA, address tokenB, int24 tickSpacing) external returns (address _clGauge);
/// @notice claim concentrated liquidity gauge rewards for specific NFP token ids
/// @param _gauges array of gauges
/// @param _tokens two dimensional array for the tokens to claim
/// @param _nfpTokenIds two dimensional array for the NFPs
function claimClGaugeRewards(
address[] calldata _gauges,
address[][] calldata _tokens,
uint256[][] calldata _nfpTokenIds
) external;
/// @notice claim arbitrary rewards from specific feeDists
/// @param owner address of the owner
/// @param _feeDistributors address of the feeDists
/// @param _tokens two dimensional array for the tokens to claim
function claimIncentives(address owner, address[] calldata _feeDistributors, address[][] calldata _tokens)
external;
/// @notice claim arbitrary rewards from specific feeDists and break up legacy pairs
/// @param owner address of the owner
/// @param _feeDistributors address of the feeDists
/// @param _tokens two dimensional array for the tokens to claim
function claimLegacyIncentives(address owner, address[] calldata _feeDistributors, address[][] calldata _tokens)
external;
/// @notice claim arbitrary rewards from specific gauges
/// @param _gauges address of the gauges
/// @param _tokens two dimensional array for the tokens to claim
function claimRewards(address[] calldata _gauges, address[][] calldata _tokens) external;
/// @notice distribute emissions to a gauge for a specific period
/// @param _gauge address of the gauge
/// @param _period value of the period
function distributeForPeriod(address _gauge, uint256 _period) external;
/// @notice attempt distribution of emissions to all gauges
function distributeAll() external;
/// @notice distribute emissions to gauges by index
/// @param startIndex start of the loop
/// @param endIndex end of the loop
function batchDistributeByIndex(uint256 startIndex, uint256 endIndex) external;
/// @notice lets governance update lastDistro period for a gauge
/// @dev should only be used if distribute() is running out of gas
/// @dev gaugePeriodDistributed will stop double claiming
/// @param _gauge gauge to update
/// @param _period period to update to
function updateLastDistro(address _gauge, uint256 _period) external;
/// @notice returns the votes cast for a tokenID
/// @param owner address of the owner
/// @return votes an array of votes casted
/// @return weights an array of the weights casted per pool
function getVotes(address owner, uint256 period)
external
view
returns (address[] memory votes, uint256[] memory weights);
/// @notice returns an array of all the pools
/// @return _pools the array of pools
function getAllPools() external view returns (address[] memory _pools);
/// @notice returns the length of pools
function getPoolsLength() external view returns (uint256);
/// @notice returns the pool at index
function getPool(uint256 index) external view returns (address);
/// @notice returns an array of all the gauges
/// @return _gauges the array of gauges
function getAllGauges() external view returns (address[] memory _gauges);
/// @notice returns the length of gauges
function getGaugesLength() external view returns (uint256);
/// @notice returns the gauge at index
function getGauge(uint256 index) external view returns (address);
/// @notice returns an array of all the feeDists
/// @return _feeDistributors the array of feeDists
function getAllFeeDistributors() external view returns (address[] memory _feeDistributors);
/// @notice sets the xRamRatio default
function setGlobalRatio(uint256 _xRatio) external;
/// @notice whether the token is whitelisted in governance
function isWhitelisted(address _token) external view returns (bool _tf);
/// @notice function for removing malicious or stuffed tokens
function removeFeeDistributorReward(address _feeDist, address _token) external;
/// @notice returns the total votes for a pool in a specific period
/// @param pool the pool address to check
/// @param period the period to check
/// @return votes the total votes for the pool in that period
function poolTotalVotesPerPeriod(address pool, uint256 period) external view returns (uint256 votes);
/// @notice returns the pool address for a given gauge
/// @param gauge address of the gauge
/// @return pool address of the pool
function poolForGauge(address gauge) external view returns (address pool);
/// @notice returns the pool address for a given feeDistributor
/// @param feeDistributor address of the feeDistributor
/// @return pool address of the pool
function poolForFeeDistributor(address feeDistributor) external view returns (address pool);
/// @notice returns the voting power used by a voter for a period
/// @param user address of the user
/// @param period the period to check
function userVotingPowerPerPeriod(address user, uint256 period) external view returns (uint256 votingPower);
/// @notice returns the total votes for a specific period
/// @param period the period to check
/// @return weight the total votes for that period
function totalVotesPerPeriod(uint256 period) external view returns (uint256 weight);
/// @notice returns the total rewards allocated for a specific period
/// @param period the period to check
/// @return amount the total rewards for that period
function totalRewardPerPeriod(uint256 period) external view returns (uint256 amount);
/// @notice returns the last distribution period for a gauge
/// @param _gauge address of the gauge
/// @return period the last period distributions occurred
function lastDistro(address _gauge) external view returns (uint256 period);
/// @notice returns if the gauge is a Cl gauge
/// @param gauge the gauge to check
function isClGauge(address gauge) external view returns (bool);
/// @notice returns if the gauge is a legacy gauge
/// @param gauge the gauge to check
function isLegacyGauge(address gauge) external view returns (bool);
/// @notice sets a new NFP manager
function setNfpManager(address _nfpManager) external;
/// @notice sets the minimum time threshold for rewarder (in seconds)
function setTimeThresholdForRewarder(uint256 _timeThreshold) external;
/// @notice returns all voters for a period
function getAllVotersPerPeriod(uint256 period) external view returns (address[] memory);
/// @notice returns the length of all voters for a period
function getAllVotersPerPeriodLength(uint256 period) external view returns (uint256);
/// @notice returns voter at index for a period
function getAllVotersPerPeriodAt(uint256 period, uint256 index) external view returns (address);
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IVoter} from "./IVoter.sol";
import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";
interface IXRex is IERC20 {
event InstantExit(address indexed user, uint256);
event NewSlashingPenalty(uint256 penalty);
event Converted(address indexed user, uint256);
event Exemption(address indexed candidate, bool status, bool success);
event XRamRedeemed(address indexed user, uint256);
event NewOperator(address indexed o, address indexed n);
event Rebase(address indexed caller, uint256 amount);
event NewRebaseThreshold(uint256 threshold);
/// @notice address of the rex token
function REX() external view returns (IERC20);
/// @notice address of the voter
function VOTER() external view returns (IVoter);
function MINTER() external view returns (address);
function ACCESS_HUB() external view returns (address);
/// @notice address of the operator
function operator() external view returns (address);
/// @notice address of the VoteModule
function VOTE_MODULE() external view returns (address);
/// @notice max slashing amount
function SLASHING_PENALTY() external view returns (uint256);
/// @notice denominator
function BASIS() external view returns (uint256);
function rex() external view returns (address);
/// @notice the last period rebases were distributed
function lastDistributedPeriod() external view returns (uint256);
/// @notice amount of pvp rebase penalties accumulated pending to be distributed
function pendingRebase() external view returns (uint256);
/// @notice dust threshold before a rebase can happen
function rebaseThreshold() external view returns (uint256);
/// @notice pauses the contract
function pause() external;
/// @notice unpauses the contract
function unpause() external;
/**
*
*/
// General use functions
/**
*
*/
/// @dev mints xREX for each rex.
function convertEmissionsToken(uint256 _amount) external;
/// @notice function called by the minter to send the rebases once a week
function rebase() external;
/**
* @dev exit instantly with a penalty
* @param _amount amount of xREX to exit
*/
function exit(uint256 _amount) external returns (uint256 _exitedAmount);
/**
*
*/
// Permissioned functions, timelock/operator gated
/**
*
*/
/// @dev allows the operator to redeem collected xREX
function operatorRedeem(uint256 _amount) external;
/// @dev allows rescue of any non-stake token
function rescueTrappedTokens(address[] calldata _tokens, uint256[] calldata _amounts) external;
/// @notice migrates the operator to another contract
function migrateOperator(address _operator) external;
/// @notice set exemption status for an address
function setExemption(address[] calldata _exemptee, bool[] calldata _exempt) external;
function setExemptionTo(address[] calldata _exemptee, bool[] calldata _exempt) external;
/// @notice set dust threshold before a rebase can happen
function setRebaseThreshold(uint256 _newThreshold) external;
/**
*
*/
// Getter functions
/**
*
*/
/// @notice returns the amount of REX within the contract
function getBalanceResiding() external view returns (uint256);
/// @notice whether the address is exempt
/// @param _who who to check
/// @return _exempt whether it's exempt
function isExempt(address _who) external view returns (bool _exempt);
/// @notice whether the address is exempt to
/// @param _who who to check
/// @return _exempt whether it's exempt
function isExemptTo(address _who) external view returns (bool _exempt);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title Central Errors Library
/// @notice Contains all custom errors used across the protocol
/// @dev Centralized error definitions to prevent redundancy
library Errors {
/*//////////////////////////////////////////////////////////////
VOTER ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when attempting to interact with an already active gauge
/// @param gauge The address of the gauge
error ACTIVE_GAUGE(address gauge);
/// @notice Thrown when attempting to interact with an inactive gauge
/// @param gauge The address of the gauge
error GAUGE_INACTIVE(address gauge);
/// @notice Thrown when attempting to whitelist an already whitelisted token
/// @param token The address of the token
error ALREADY_WHITELISTED(address token);
/// @notice Thrown when caller is not authorized to perform an action
/// @param caller The address of the unauthorized caller
error NOT_AUTHORIZED(address caller);
/// @notice Thrown when token is not whitelisted
/// @param token The address of the non-whitelisted token
error NOT_WHITELISTED(address token);
/// @notice Thrown when both tokens in a pair are not whitelisted
error BOTH_NOT_WHITELISTED();
/// @notice Thrown when address is not a valid pool
/// @param pool The invalid pool address
error NOT_POOL(address pool);
/// @notice Thrown when contract is not initialized
error NOT_INIT();
/// @notice Thrown when array lengths don't match
error LENGTH_MISMATCH();
/// @notice Thrown when pool doesn't have an associated gauge
/// @param pool The address of the pool
error NO_GAUGE(address pool);
/// @notice Thrown when rewards are already distributed for a period
/// @param gauge The gauge address
/// @param period The distribution period
error ALREADY_DISTRIBUTED(address gauge, uint256 period);
/// @notice Thrown when attempting to vote with zero amount
/// @param pool The pool address
error ZERO_VOTE(address pool);
/// @notice Thrown when ratio exceeds maximum allowed
/// @param _xRatio The excessive ratio value
error RATIO_TOO_HIGH(uint256 _xRatio);
/// @notice Thrown when vote operation fails
error VOTE_UNSUCCESSFUL();
/*//////////////////////////////////////////////////////////////
GAUGE V3 ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when the pool already has a gauge
/// @param pool The address of the pool
error GAUGE_EXISTS(address pool);
/// @notice Thrown when caller is not the voter
/// @param caller The address of the invalid caller
error NOT_VOTER(address caller);
/// @notice Thrown when amount is not greater than zero
/// @param amt The invalid amount
error NOT_GT_ZERO(uint256 amt);
/// @notice Thrown when attempting to claim future rewards
error CANT_CLAIM_FUTURE();
/// @notice Throw when gauge can't determine if using secondsInRange from the pool is safe
error NEED_TEAM_TO_UPDATE();
/*//////////////////////////////////////////////////////////////
GAUGE ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when amount is zero
error ZERO_AMOUNT();
/// @notice Thrown when stake notification fails
error CANT_NOTIFY_STAKE();
/// @notice Thrown when reward amount is too high
error REWARD_TOO_HIGH();
/// @notice Thrown when amount exceeds remaining balance
/// @param amount The requested amount
/// @param remaining The remaining balance
error NOT_GREATER_THAN_REMAINING(uint256 amount, uint256 remaining);
/// @notice Thrown when token operation fails
/// @param token The address of the problematic token
error TOKEN_ERROR(address token);
/// @notice Thrown when an address is not an NfpManager
error NOT_NFP_MANAGER(address nfpManager);
/*//////////////////////////////////////////////////////////////
FEE DISTRIBUTOR ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when period is not finalized
/// @param period The unfinalized period
error NOT_FINALIZED(uint256 period);
/// @notice Thrown when the destination of a redirect is not a feeDistributor
/// @param destination Destination of the redirect
error NOT_FEE_DISTRIBUTOR(address destination);
/// @notice Thrown when the destination of a redirect's pool/pair has completely different tokens
error DIFFERENT_DESTINATION_TOKENS();
/*//////////////////////////////////////////////////////////////
PAIR ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when ratio is unstable
error UNSTABLE_RATIO();
/// @notice Thrown when safe transfer fails
error SAFE_TRANSFER_FAILED();
/// @notice Thrown on arithmetic overflow
error OVERFLOW();
/// @notice Thrown when skim operation is disabled
error SKIM_DISABLED();
/// @notice Thrown when insufficient liquidity is minted
error INSUFFICIENT_LIQUIDITY_MINTED();
/// @notice Thrown when insufficient liquidity is burned
error INSUFFICIENT_LIQUIDITY_BURNED();
/// @notice Thrown when output amount is insufficient
error INSUFFICIENT_OUTPUT_AMOUNT();
/// @notice Thrown when input amount is insufficient
error INSUFFICIENT_INPUT_AMOUNT();
/// @notice Generic insufficient liquidity error
error INSUFFICIENT_LIQUIDITY();
/// @notice Invalid transfer error
error INVALID_TRANSFER();
/// @notice K value error in AMM
error K();
/*//////////////////////////////////////////////////////////////
PAIR FACTORY ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when fee is too high
error FEE_TOO_HIGH();
/// @notice Thrown when fee is zero
error ZERO_FEE();
/// @notice Thrown when token assortment is invalid
error INVALID_ASSORTMENT();
/// @notice Thrown when address is zero
error ZERO_ADDRESS();
/// @notice Thrown when pair already exists
error PAIR_EXISTS();
/// @notice Thrown when fee split is invalid
error INVALID_FEE_SPLIT();
/*//////////////////////////////////////////////////////////////
FEE RECIPIENT FACTORY ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when treasury fee is invalid
error INVALID_TREASURY_FEE();
/*//////////////////////////////////////////////////////////////
ROUTER ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when deadline has expired
error EXPIRED();
/// @notice Thrown when tokens are identical
error IDENTICAL();
/// @notice Thrown when amount is insufficient
error INSUFFICIENT_AMOUNT();
/// @notice Thrown when path is invalid
error INVALID_PATH();
/// @notice Thrown when token B amount is insufficient
error INSUFFICIENT_B_AMOUNT();
/// @notice Thrown when token A amount is insufficient
error INSUFFICIENT_A_AMOUNT();
/// @notice Thrown when input amount is excessive
error EXCESSIVE_INPUT_AMOUNT();
/// @notice Thrown when ETH transfer fails
error ETH_TRANSFER_FAILED();
/// @notice Thrown when reserves are invalid
error INVALID_RESERVES();
/*//////////////////////////////////////////////////////////////
MINTER ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when epoch 0 has already started
error STARTED();
/// @notice Thrown when emissions haven't started
error EMISSIONS_NOT_STARTED();
/// @notice Thrown when deviation is too high
error TOO_HIGH();
/// @notice Thrown when no value change detected
error NO_CHANGE();
/// @notice Thrown when updating emissions in same period
error SAME_PERIOD();
/// @notice Thrown when contract setup is invalid
error INVALID_CONTRACT();
/// @notice Thrown when legacy factory doesn't have feeSplitWhenNoGauge on
error FEE_SPLIT_WHEN_NO_GAUGE_IS_OFF();
/*//////////////////////////////////////////////////////////////
ACCESS HUB ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when addresses are identical
error SAME_ADDRESS();
/// @notice Thrown when caller is not timelock
/// @param caller The invalid caller address
error NOT_TIMELOCK(address caller);
/// @notice Thrown when manual execution fails
/// @param reason The failure reason
error MANUAL_EXECUTION_FAILURE(bytes reason);
/// @notice Thrown when kick operation is forbidden
/// @param target The target address
error KICK_FORBIDDEN(address target);
/// @notice Thrown when the function called on AccessHub is not found
error FUNCTION_NOT_FOUND();
/// @notice Thrown when the expansion pack can't be added
error FAILED_TO_ADD();
/// @notice Thrown when the expansion pack can't be removed
error FAILED_TO_REMOVE();
/// @notice Throw when someone other than x33Adapter calls rebaseX33Callback
error NOT_X33_ADAPTER();
/*//////////////////////////////////////////////////////////////
VOTE MODULE ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when caller is not xRam
error NOT_XRAM();
/// @notice Thrown when cooldown period is still active
error COOLDOWN_ACTIVE();
/// @notice Thrown when caller is not vote module
error NOT_VOTEMODULE();
/// @notice Thrown when caller is unauthorized
error UNAUTHORIZED();
/// @notice Thrown when caller is not access hub
error NOT_ACCESSHUB();
/// @notice Thrown when address is invalid
error INVALID_ADDRESS();
/*//////////////////////////////////////////////////////////////
X33 ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when value is zero
error ZERO();
/// @notice Thrown when amount is insufficient
error NOT_ENOUGH();
/// @notice Thrown when value doesn't conform to scale
/// @param value The non-conforming value
error NOT_CONFORMED_TO_SCALE(uint256 value);
/// @notice Thrown when contract is locked
error LOCKED();
/// @notice Thrown when rebase is in progress
error REBASE_IN_PROGRESS();
/// @notice Thrown when aggregator reverts
/// @param reason The revert reason
error AGGREGATOR_REVERTED(bytes reason);
/// @notice Thrown when output amount is too low
/// @param amount The insufficient amount
error AMOUNT_OUT_TOO_LOW(uint256 amount);
/// @notice Thrown when aggregator is not whitelisted
/// @param aggregator The non-whitelisted aggregator address
error AGGREGATOR_NOT_WHITELISTED(address aggregator);
/// @notice Thrown when token is forbidden
/// @param token The forbidden token address
error FORBIDDEN_TOKEN(address token);
/*//////////////////////////////////////////////////////////////
XRAM ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when caller is not minter
error NOT_MINTER();
/// @notice Thrown when no vest exists
error NO_VEST();
/// @notice Thrown when already exempt
error ALREADY_EXEMPT();
/// @notice Thrown when not exempt
error NOT_EXEMPT();
/// @notice Thrown when rescue operation is not allowed
error CANT_RESCUE();
/// @notice Thrown when array lengths mismatch
error ARRAY_LENGTHS();
/// @notice Thrown when vesting periods overlap
error VEST_OVERLAP();
/*//////////////////////////////////////////////////////////////
V3 FACTORY ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when tokens are identical
error IDENTICAL_TOKENS();
/// @notice Thrown when fee is too large
error FEE_TOO_LARGE();
/// @notice Address zero error
error ADDRESS_ZERO();
/// @notice Fee zero error
error F0();
/// @notice Thrown when value is out of bounds
/// @param value The out of bounds value
error OOB(uint8 value);
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
interface IVoteModule {
/**
* Events
*/
event Deposit(address indexed from, uint256 amount);
event Withdraw(address indexed from, uint256 amount);
event NotifyReward(address indexed from, uint256 amount);
event ClaimRewards(address indexed from, uint256 amount);
event ExemptedFromCooldown(address indexed candidate, bool status);
event NewDuration(uint256 oldDuration, uint256 newDuration);
event NewCooldown(uint256 oldCooldown, uint256 newCooldown);
event Delegate(address indexed delegator, address indexed delegatee, bool indexed isAdded);
event SetAdmin(address indexed owner, address indexed operator, bool indexed isAdded);
/**
* Functions
*/
function delegates(address) external view returns (address);
/// @notice mapping for admins for a specific address
/// @param owner the owner to check against
/// @return operator the address that is designated as an admin/operator
function admins(address owner) external view returns (address operator);
function accessHub() external view returns (address);
/// @notice reward supply for a period
function rewardSupply(uint256 period) external view returns (uint256);
/// @notice user claimed reward amount for a period
/// @dev same mapping order as FeeDistributor so the name is a bit odd
function userClaimed(uint256 period, address owner) external view returns (uint256);
/// @notice last claimed period for a user
function userLastClaimPeriod(address owner) external view returns (uint256);
/// @notice returns the current period
function getPeriod() external view returns (uint256);
/// @notice returns the amount of unclaimed rebase earned by the user
function earned(address account) external view returns (uint256 _reward);
/// @notice returns the amount of unclaimed rebase earned by the user for a period
function periodEarned(uint256 period, address user) external view returns (uint256 amount);
/// @notice the time which users can deposit and withdraw
function unlockTime() external view returns (uint256 _timestamp);
/// @notice claims pending rebase rewards
function getReward() external;
/// @notice claims pending rebase rewards for a period
function getPeriodReward(uint256 period) external;
/// @notice allows users to set their own last claimed period in case they haven't claimed in a while
/// @param period the new period to start loops from
function setUserLastClaimPeriod(uint256 period) external;
/// @notice deposits all xREX in the caller's wallet
function depositAll() external;
/// @notice deposit a specified amount of xRam
function deposit(uint256 amount) external;
/// @notice withdraw all xREX
function withdrawAll() external;
/// @notice withdraw a specified amount of xREX
function withdraw(uint256 amount) external;
/// @notice check for admin perms
/// @param operator the address to check
/// @param owner the owner to check against for permissions
function isAdminFor(address operator, address owner) external view returns (bool approved);
/// @notice check for delegations
/// @param delegate the address to check
/// @param owner the owner to check against for permissions
function isDelegateFor(address delegate, address owner) external view returns (bool approved);
/// @notice used by the xREX contract to notify pending rebases
/// @param amount the amount of REX to be notified from exit penalties
function notifyRewardAmount(uint256 amount) external;
/// @notice the address of the xREX token (staking/voting token)
/// @return _xRex the address
function xRex() external view returns (address _xRex);
/// @notice address of the voter contract
/// @return _voter the voter contract address
function voter() external view returns (address _voter);
/// @notice returns the total voting power (equal to total supply in the VoteModule)
/// @return _totalSupply the total voting power
function totalSupply() external view returns (uint256 _totalSupply);
/// @notice voting power
/// @param user the address to check
/// @return amount the staked balance
function balanceOf(address user) external view returns (uint256 amount);
/// @notice delegate voting perms to another address
/// @param delegatee who you delegate to
/// @dev set address(0) to revoke
function delegate(address delegatee) external;
/// @notice give admin permissions to a another address
/// @param operator the address to give administrative perms to
/// @dev set address(0) to revoke
function setAdmin(address operator) external;
function cooldownExempt(address) external view returns (bool);
function setCooldownExemption(address, bool) external;
/// @notice lock period after rebase starts accruing
function cooldown() external returns (uint256);
function setNewCooldown(uint256) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC-20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// 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;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard ERC-20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC-721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC-1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}{
"remappings": [
"@layerzerolabs/=node_modules/@layerzerolabs/",
"@layerzerolabs/lz-evm-protocol-v2/=node_modules/@layerzerolabs/lz-evm-protocol-v2/",
"@openzeppelin-contracts-upgradeable/=dependencies/@openzeppelin-contracts-upgradeable-5.1.0/",
"@openzeppelin-contracts/contracts/=dependencies/@openzeppelin-contracts-5.1.0/",
"@openzeppelin/contracts-upgradeable/=dependencies/@openzeppelin-contracts-upgradeable-5.1.0/",
"@openzeppelin/contracts/=dependencies/@openzeppelin-contracts-5.1.0/",
"erc4626-tests/=dependencies/erc4626-property-tests-1.0/",
"forge-std/=dependencies/forge-std-1.9.4/src/",
"permit2/=lib/permit2/",
"@openzeppelin-3.4.2/=node_modules/@openzeppelin-3.4.2/",
"@openzeppelin-contracts-5.1.0/=dependencies/@openzeppelin-contracts-5.1.0/",
"@openzeppelin-contracts-upgradeable-5.1.0/=dependencies/@openzeppelin-contracts-upgradeable-5.1.0/",
"@uniswap/=node_modules/@uniswap/",
"base64-sol/=node_modules/base64-sol/",
"erc4626-property-tests-1.0/=dependencies/erc4626-property-tests-1.0/",
"eth-gas-reporter/=node_modules/eth-gas-reporter/",
"forge-std-1.9.4/=dependencies/forge-std-1.9.4/src/",
"hardhat/=node_modules/hardhat/",
"solidity-bytes-utils/=node_modules/solidity-bytes-utils/",
"solmate/=node_modules/solmate/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": true,
"libraries": {
"contracts/libraries/VoterGovernanceActions.sol": {
"VoterGovernanceActions": "0x99A06527CdBE0a3CA305c494542C973BEF1A9143"
},
"contracts/libraries/VoterRewardClaimers.sol": {
"VoterRewardClaimers": "0xcE31D08973AB92066A290C03F6165235E1a73f94"
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_rex","type":"address"},{"internalType":"address","name":"_voter","type":"address"},{"internalType":"address","name":"_operator","type":"address"},{"internalType":"address","name":"_accessHub","type":"address"},{"internalType":"address","name":"_voteModule","type":"address"},{"internalType":"address","name":"_minter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ARRAY_LENGTHS","type":"error"},{"inputs":[],"name":"CANT_RESCUE","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"NOT_AUTHORIZED","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"NOT_WHITELISTED","type":"error"},{"inputs":[],"name":"NO_CHANGE","type":"error"},{"inputs":[],"name":"ZERO","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"Converted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"candidate","type":"address"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"},{"indexed":false,"internalType":"bool","name":"success","type":"bool"}],"name":"Exemption","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"InstantExit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"o","type":"address"},{"indexed":true,"internalType":"address","name":"n","type":"address"}],"name":"NewOperator","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"threshold","type":"uint256"}],"name":"NewRebaseThreshold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"penalty","type":"uint256"}],"name":"NewSlashingPenalty","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Rebase","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"XRamRedeemed","type":"event"},{"inputs":[],"name":"ACCESS_HUB","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASIS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REX","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SLASHING_PENALTY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VOTER","outputs":[{"internalType":"contract IVoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VOTE_MODULE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"convertEmissionsToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"exit","outputs":[{"internalType":"uint256","name":"_exitedAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getBalanceResiding","outputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_who","type":"address"}],"name":"isExempt","outputs":[{"internalType":"bool","name":"_exempt","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_who","type":"address"}],"name":"isExemptTo","outputs":[{"internalType":"bool","name":"_exempt","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastDistributedPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"migrateOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"operatorRedeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingRebase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rebaseThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"rescueTrappedTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rex","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_exemptee","type":"address[]"},{"internalType":"bool[]","name":"_exempt","type":"bool[]"}],"name":"setExemption","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_exemptee","type":"address[]"},{"internalType":"bool[]","name":"_exempt","type":"bool[]"}],"name":"setExemptionTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newThreshold","type":"uint256"}],"name":"setRebaseThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
61012080604052346103415760c0816126608038038091610020828561055e565b8339810103126103415761003381610581565b61003f60208301610581565b9161004c60408201610581565b9161005960608301610581565b9061007260a061006b60808601610581565b9401610581565b9361007b610595565b95610084610595565b875190976001600160401b03821161045b5760035490600182811c92168015610554575b602083101461043b5781601f8493116104e4575b50602090601f831160011461047c57600092610471575b50508160011b916000199060031b1c1916176003555b86516001600160401b03811161045b57600454600181811c91168015610451575b602082101461043b57601f81116103d6575b506020601f821160011461036557908060209897969594939260049a60009261035a575b50508160011b916000199060031b1c19161788555b600580546001600160a01b0394851660e052919093166101008190526080969096526001600160a81b03191660089190911b610100600160a81b031617905560a05260c0526101a3816105c5565b506005546101bc9060081c6001600160a01b03166105c5565b5060c0516101d2906001600160a01b03166105c5565b5060c0516101e8906001600160a01b0316610658565b50604051631ed2419560e01b815292839182905afa90811561034e57600091610317575b50600a55670de0b6b3a7640000600c557f6001f93d1361f13fa994a862c252794b9526d07cb0e34c9fe2e01c4c17e7319d6020604051670de0b6b3a76400008152a1604051611f9090816106d082396080518181816101c201526105b4015260a05181818161029e015281816104bf015281816105090152818161095a01528181610ae301528181610d3201528181610ec001528181610f57015261106d015260c05181818161065e0152610cab015260e0518181816102cf01528181610423015281816106a401528181610bde01528181610e7a015281816110ee01526112f40152610100518181816105f801528181610a9d0152818161140d015281816119af0152611bd30152f35b90506020813d602011610346575b816103326020938361055e565b8101031261034157513861020c565b600080fd5b3d9150610325565b6040513d6000823e3d90fd5b015190503880610140565b601f198216986004600052816000209960005b8181106103be575099600192849260209b9a999897969560049d106103a5575b505050811b018855610155565b015160001960f88460031b161c19169055388080610398565b838301518c556001909b019a60209384019301610378565b60046000527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b601f830160051c81019160208410610431575b601f0160051c01905b818110610425575061011c565b60008155600101610418565b909150819061040f565b634e487b7160e01b600052602260045260246000fd5b90607f169061010a565b634e487b7160e01b600052604160045260246000fd5b0151905038806100d3565b600360009081528281209350601f198516905b8181106104cc57509084600195949392106104b3575b505050811b016003556100e9565b015160001960f88460031b161c191690553880806104a5565b9293602060018192878601518155019501930161048f565b60036000529091507fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b601f840160051c8101916020851061054a575b90601f859493920160051c01905b81811061053b57506100bc565b6000815584935060010161052e565b9091508190610520565b91607f16916100a8565b601f909101601f19168101906001600160401b0382119082101761045b57604052565b51906001600160a01b038216820361034157565b60408051919082016001600160401b0381118382101761045b5760405260048252630f0a48ab60e31b6020830152565b80600052600760205260406000205415600014610652576006546801000000000000000081101561045b57600181018060065581101561063c577ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0181905560065460009182526007602052604090912055600190565b634e487b7160e01b600052603260045260246000fd5b50600090565b80600052600960205260406000205415600014610652576008546801000000000000000081101561045b57600181018060085581101561063c577ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3018190556008546000918252600960205260409091205560019056fe608080604052600436101561001357600080fd5b600090813560e01c90816306fdde031461160057508063095ea7b31461155657806312e82674146112a857806318160ddd1461128a57806323b872dd146111aa57806325d64f4b1461118c578063313ce5671461117057806332fef3cf146110525780633409b2b014610e64578063353140d014610f3e5780633f4ba83a14610ea957806347686e4814610e64578063528cfa9814610e4657806352d38e5d14610e28578063570ca73514610dfb5780635c975abb14610dd85780636379808f14610d1257806370a0823114610cda5780637dd51d7a14610c955780637f8661a114610b545780638456cb5914610acc5780638ebf2fd614610a875780638f7b565b14610a6957806394126bb11461094157806395d89b4114610838578063a9059cbb14610806578063ad5dff73146107cb578063af14052c14610595578063b7f045e914610577578063b890ebf6146104ee578063b989216a146104a9578063bacbf61b146103f6578063beb7dc3414610284578063da431ca514610249578063dd62ed3e146101f45763fe6d8124146101ad57600080fd5b346101f157806003193601126101f1576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b80fd5b50346101f15760403660031901126101f1576040610210611702565b91610219611718565b9260018060a01b031681526001602052209060018060a01b03166000526020526020604060002054604051908152f35b50346101f15760203660031901126101f1576020906040906001600160a01b03610271611702565b1681526009835220541515604051908152f35b50346101f1576102933661175f565b91929091906102cd337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168114611801565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031693855b818110610305578680f35b856001600160a01b0361032161031c84868861182a565b61185d565b16146103e7576103949060206001600160a01b0361034361031c84878961182a565b60055460081c6001600160a01b0316911661035f84898b61182a565b60405163a9059cbb60e01b81526001600160a01b039093166004840152356024830152909384919082908c9082906044820190565b03925af19182156103dc576001926103ae575b50016102fa565b6103ce9060203d81116103d5575b6103c681836117b1565b8101906117e9565b50386103a7565b503d6103bc565b6040513d8a823e3d90fd5b63512428f960e01b8752600487fd5b50346101f157806003193601126101f1576040516370a0823160e01b8152306004820152906020826024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561049d5790610465575b602090604051908152f35b506020813d602011610495575b8161047f602093836117b1565b81010312610490576020905161045a565b600080fd5b3d9150610472565b604051903d90823e3d90fd5b50346101f157806003193601126101f1576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346101f15760203660031901126101f157600435610538337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168114611801565b80600c5403610545575080f35b6020817f6001f93d1361f13fa994a862c252794b9526d07cb0e34c9fe2e01c4c17e7319d92600c55604051908152a180f35b50346101f157806003193601126101f1576020600a54604051908152f35b50346101f157806003193601126101f1576105ae611894565b6105e3337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168114611801565b604051631ed2419560e01b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610754578291610799575b50600a5481118061078b575b610644575080f35b600a55600b80549082905560405163095ea7b360e01b81527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0381166004830152602482018390529192919060208180604481010381867f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1801561078057610763575b506001600160a01b0316803b1561075f57818091602460405180948193633c6b16ab60e01b83528860048401525af1801561075457610744575b50906040519081527fcf0cf43969b3f0a08a20481cfa1fd31d1023ab827f0babb8d8125862a9c403f860203392a280f35b8161074e916117b1565b38610713565b6040513d84823e3d90fd5b5080fd5b61077b9060203d6020116103d5576103c681836117b1565b6106d9565b6040513d85823e3d90fd5b50600b54600c54111561063c565b90506020813d6020116107c3575b816107b4602093836117b1565b8101031261075f575138610630565b3d91506107a7565b50346101f15760203660031901126101f1576020906040906001600160a01b036107f3611702565b1681526007835220541515604051908152f35b50346101f15760403660031901126101f15761082d610823611702565b60243590336118b1565b602060405160018152f35b50346101f157806003193601126101f1576040519080600454908160011c91600181168015610937575b602084108114610923578386529081156108fc575060011461089f575b61089b8461088f818603826117b1565b604051918291826116b9565b0390f35b600481527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b939250905b8082106108e25750909150810160200161088f8261087f565b9192600181602092548385880101520191019092916108c9565b60ff191660208087019190915292151560051b8501909201925061088f915083905061087f565b634e487b7160e01b83526022600452602483fd5b92607f1692610862565b50346101f1576109503661175f565b91929091610989337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168114611801565b808403610a5a57845b81811061099d578580f35b806109b36109ae600193858861182a565b611850565b15610a38576109d5828060a01b036109cf61031c848a8961182a565b16611f05565b7f0c26de26c21d52b9af1eae2bc6d3c4f03cf66cf139d32166af29b8aed7135192610a0461031c848a8961182a565b91610a136109ae85888b61182a565b604080519115158252911515602082015260a086901b8690039390931692a201610992565b610a55828060a01b03610a4f61031c848a8961182a565b16611df6565b6109d5565b630f40213560e21b8552600485fd5b50346101f157806003193601126101f1576020600b54604051908152f35b50346101f157806003193601126101f1576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346101f157806003193601126101f157610b12337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168114611801565b610b1a611894565b600160ff1960055416176005557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a180f35b50346101f15760203660031901126101f157600435610b71611894565b8015610c86576207a12081028181046207a12003610c7257620f4240900480820391808311610c5e5790610ba8610bb09233611aee565b600b54611871565b600b5560405163a9059cbb60e01b815233600482015260248101829052602081604481866001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000165af180156107805760209350610c43575b506040518181527fa8a63b0531e55ae709827fb089d01034e24a200ad14dc710dfa9e962005f629a833392a2604051908152f35b610c5990833d85116103d5576103c681836117b1565b610c0f565b634e487b7160e01b84526011600452602484fd5b634e487b7160e01b83526011600452602483fd5b632c7d31e560e11b8252600482fd5b50346101f157806003193601126101f1576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346101f15760203660031901126101f1576020906040906001600160a01b03610d02611702565b1681528083522054604051908152f35b50346101f15760203660031901126101f157610d2c611702565b610d61337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168114611801565b600554906001600160a01b0380821690600884901c16818114610dc6577ff1e04d73c4304b5ff164f9d10c7473e2a1593b740674a6107975e2a7001c1e5c8580a3610100600160a81b031990911660089190911b610100600160a81b03161760055580f35b600162067eab60e51b03198552600485fd5b50346101f157806003193601126101f157602060ff600554166040519015158152f35b50346101f157806003193601126101f15760055460405160089190911c6001600160a01b03168152602090f35b50346101f157806003193601126101f1576020600c54604051908152f35b50346101f157806003193601126101f1576020604051620f42408152f35b50346101f157806003193601126101f1576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50346101f157806003193601126101f157610eef337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168114611801565b60055460ff811615610f2f5760ff19166005557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a180f35b638dfc202b60e01b8252600482fd5b50346101f157610f4d3661175f565b91929091610f86337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168114611801565b808403610a5a57845b818110610f9a578580f35b80610fab6109ae600193858861182a565b1561103057610fcd828060a01b03610fc761031c848a8961182a565b16611eaa565b7f0c26de26c21d52b9af1eae2bc6d3c4f03cf66cf139d32166af29b8aed7135192610ffc61031c848a8961182a565b9161100b6109ae85888b61182a565b604080519115158252911515602082015260a086901b8690039390931692a201610f8f565b61104d828060a01b0361104761031c848a8961182a565b16611d0e565b610fcd565b50346101f15760203660031901126101f15760043561109c337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168114611801565b6005546110b690829060081c6001600160a01b0316611aee565b60055460405163a9059cbb60e01b815260089190911c6001600160a01b031660048201526024810182905260208180604481010381867f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1801561078057611153575b506040519081527fcdbac541db49fbbf60d76d4efac473eebe6a9b957ace755163cbdf13f03515eb60203092a280f35b61116b9060203d6020116103d5576103c681836117b1565b611123565b50346101f157806003193601126101f157602060405160128152f35b50346101f157806003193601126101f15760206040516207a1208152f35b50346101f15760603660031901126101f1576111c4611702565b6111cc611718565b6001600160a01b038216808452600160208181526040808720338852909152852054604435949290918201611208575b505061082d93506118b1565b84821061126f57801561125b57331561124757604086869261082d9852600160205281812060018060a01b0333168252602052209103905538806111fc565b634a1406b160e11b86526004869052602486fd5b63e602df0560e01b86526004869052602486fd5b6064868684637dc7a0d960e11b835233600452602452604452fd5b50346101f157806003193601126101f1576020600254604051908152f35b50346101f15760203660031901126101f1576004356112c5611894565b8015610c86576040516323b872dd60e01b815233600482015230602482015260448101829052602081606481867f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1801561078057611539575b5033156115255781828052600760205260408320541580159061151d575b8015611516575b8015611501575b156113f75750600160ff815b16036113e35761137381600254611871565b6002553382528160205260408220818154019055604051818152827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60203393a36040519081527fa428517b481b65176e7c35a57b564d5cf943c8462468b8a0f025fa689173f90160203392a280f35b630b7b234960e01b82526004829052602482fd5b60405163aa79979b60e01b8152600481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316602082602481845afa9182156114f65785926114d5575b508115611476575b50611464575b60ff600191611361565b5061146e82611f05565b50600161145a565b6024915060209060405192838092635397401b60e01b82528860048301525afa9081156114ca5784916114ab575b5038611454565b6114c4915060203d6020116103d5576103c681836117b1565b386114a4565b6040513d86823e3d90fd5b6114ef91925060203d6020116103d5576103c681836117b1565b903861144c565b6040513d87823e3d90fd5b50338352600960205260408320541515611355565b508261134e565b506001611347565b63ec442f0560e01b82526004829052602482fd5b6115519060203d6020116103d5576103c681836117b1565b611329565b50346101f15760403660031901126101f157611570611702565b6024359033156115ec576001600160a01b03169182156115d85760408291338152600160205281812085825260205220556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b634a1406b160e11b81526004819052602490fd5b63e602df0560e01b83526004839052602483fd5b82346101f157806003193601126101f15780600354908160011c916001811680156116af575b602084108114610923578386529081156108fc57506001146116525761089b8461088f818603826117b1565b600381527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b939250905b8082106116955750909150810160200161088f8261087f565b91926001816020925483858801015201910190929161167c565b92607f1692611626565b91909160208152825180602083015260005b8181106116ec575060409293506000838284010152601f8019910116010190565b80602080928701015160408286010152016116cb565b600435906001600160a01b038216820361049057565b602435906001600160a01b038216820361049057565b9181601f840112156104905782359167ffffffffffffffff8311610490576020808501948460051b01011161049057565b60406003198201126104905760043567ffffffffffffffff8111610490578161178a9160040161172e565b929092916024359067ffffffffffffffff8211610490576117ad9160040161172e565b9091565b90601f8019910116810190811067ffffffffffffffff8211176117d357604052565b634e487b7160e01b600052604160045260246000fd5b90816020910312610490575180151581036104905790565b156118095750565b632bc10c3360e01b60009081526001600160a01b0391909116600452602490fd5b919081101561183a5760051b0190565b634e487b7160e01b600052603260045260246000fd5b3580151581036104905790565b356001600160a01b03811681036104905790565b9190820180921161187e57565b634e487b7160e01b600052601160045260246000fd5b60ff600554166118a057565b63d93c066560e01b60005260046000fd5b6001600160a01b0316908115611ad8576001600160a01b0316918215611ac257600082600052600760205260406000205415801590611aba575b8015611ab2575b8015611a9b575b156119995750600160ff815b160361198457600082815280602052604081205482811061196a5791604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef958760209652828652038282205586815280845220818154019055604051908152a3565b916064928463391434e360e21b8452600452602452604452fd5b50630b7b234960e01b60005260045260246000fd5b60405163aa79979b60e01b8152600481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316602082602481845afa918215611a6e57600092611a7a575b508115611a19575b50611a07575b60ff600191611905565b50611a1182611f05565b5060016119fd565b6024915060209060405192838092635397401b60e01b82528860048301525afa908115611a6e57600091611a4f575b50386119f7565b611a68915060203d6020116103d5576103c681836117b1565b38611a48565b6040513d6000823e3d90fd5b611a9491925060203d6020116103d5576103c681836117b1565b90386119ef565b5083600052600960205260406000205415156118f9565b5060006118f2565b5060006118eb565b63ec442f0560e01b600052600060045260246000fd5b634b637e8f60e11b600052600060045260246000fd5b6001600160a01b03168015611ad857600081600052600760205260406000205415801590611cee575b8015611ce6575b8015611cb3575b15611bbd5750600160ff815b1603611ba957600091818352826020526040832054818110611b9057817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef926020928587528684520360408620558060025403600255604051908152a3565b6064939263391434e360e21b8452600452602452604452fd5b630b7b234960e01b60005260045260246000fd5b60405163aa79979b60e01b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316602082602481845afa918215611a6e57600092611c92575b508115611c3d575b50611c2b575b60ff600191611b31565b50611c3581611f05565b506001611c21565b6024915060209060405192838092635397401b60e01b82528760048301525afa908115611a6e57600091611c73575b5038611c1b565b611c8c915060203d6020116103d5576103c681836117b1565b38611c6c565b611cac91925060203d6020116103d5576103c681836117b1565b9038611c13565b506000805260096020527fec8156718a8372b1db44bb411437d0870f3e3790d4a08526d024ce1b0b668f6b541515611b25565b506001611b1e565b506000611b17565b805482101561183a5760005260206000200190600090565b6000818152600960205260409020548015611def57600019810181811161187e5760085460001981019190821161187e57818103611d9e575b5050506008548015611d885760001901611d62816008611cf6565b8154906000199060031b1b19169055600855600052600960205260006040812055600190565b634e487b7160e01b600052603160045260246000fd5b611dd7611daf611dc0936008611cf6565b90549060031b1c9283926008611cf6565b819391549060031b91821b91600019901b19161790565b90556000526009602052604060002055388080611d47565b5050600090565b6000818152600760205260409020548015611def57600019810181811161187e5760065460001981019190821161187e57818103611e70575b5050506006548015611d885760001901611e4a816006611cf6565b8154906000199060031b1b19169055600655600052600760205260006040812055600190565b611e92611e81611dc0936006611cf6565b90549060031b1c9283926006611cf6565b90556000526007602052604060002055388080611e2f565b80600052600960205260406000205415600014611eff57600854600160401b8110156117d357611ee6611dc08260018594016008556008611cf6565b9055600854906000526009602052604060002055600190565b50600090565b80600052600760205260406000205415600014611eff57600654600160401b8110156117d357611f41611dc08260018594016006556006611cf6565b905560065490600052600760205260406000205560019056fea2646970667358221220f61b9dc53cc7078a147067df79cc354fcd7f0a22e705dcac5c011c091cb7631a64736f6c634300081c0033000000000000000000000000efd81eec32b9a8222d1842ec3d99c7532c31e348000000000000000000000000942117ec0458a8aa08669e94b52001bd43f889c1000000000000000000000000de4b22eb9f9c2c55e72e330c87663b28e9d388f7000000000000000000000000683035188e3670fda1def2a7aa5742dea28ed5f3000000000000000000000000edd7cbc9c47547d0b552d5bc2be76135f49c15b10000000000000000000000000b6d3b42861ee8abfcaac818033694e758ecc3eb
Deployed Bytecode
0x608080604052600436101561001357600080fd5b600090813560e01c90816306fdde031461160057508063095ea7b31461155657806312e82674146112a857806318160ddd1461128a57806323b872dd146111aa57806325d64f4b1461118c578063313ce5671461117057806332fef3cf146110525780633409b2b014610e64578063353140d014610f3e5780633f4ba83a14610ea957806347686e4814610e64578063528cfa9814610e4657806352d38e5d14610e28578063570ca73514610dfb5780635c975abb14610dd85780636379808f14610d1257806370a0823114610cda5780637dd51d7a14610c955780637f8661a114610b545780638456cb5914610acc5780638ebf2fd614610a875780638f7b565b14610a6957806394126bb11461094157806395d89b4114610838578063a9059cbb14610806578063ad5dff73146107cb578063af14052c14610595578063b7f045e914610577578063b890ebf6146104ee578063b989216a146104a9578063bacbf61b146103f6578063beb7dc3414610284578063da431ca514610249578063dd62ed3e146101f45763fe6d8124146101ad57600080fd5b346101f157806003193601126101f1576040517f0000000000000000000000000b6d3b42861ee8abfcaac818033694e758ecc3eb6001600160a01b03168152602090f35b80fd5b50346101f15760403660031901126101f1576040610210611702565b91610219611718565b9260018060a01b031681526001602052209060018060a01b03166000526020526020604060002054604051908152f35b50346101f15760203660031901126101f1576020906040906001600160a01b03610271611702565b1681526009835220541515604051908152f35b50346101f1576102933661175f565b91929091906102cd337f000000000000000000000000683035188e3670fda1def2a7aa5742dea28ed5f36001600160a01b03168114611801565b7f000000000000000000000000efd81eec32b9a8222d1842ec3d99c7532c31e3486001600160a01b031693855b818110610305578680f35b856001600160a01b0361032161031c84868861182a565b61185d565b16146103e7576103949060206001600160a01b0361034361031c84878961182a565b60055460081c6001600160a01b0316911661035f84898b61182a565b60405163a9059cbb60e01b81526001600160a01b039093166004840152356024830152909384919082908c9082906044820190565b03925af19182156103dc576001926103ae575b50016102fa565b6103ce9060203d81116103d5575b6103c681836117b1565b8101906117e9565b50386103a7565b503d6103bc565b6040513d8a823e3d90fd5b63512428f960e01b8752600487fd5b50346101f157806003193601126101f1576040516370a0823160e01b8152306004820152906020826024817f000000000000000000000000efd81eec32b9a8222d1842ec3d99c7532c31e3486001600160a01b03165afa90811561049d5790610465575b602090604051908152f35b506020813d602011610495575b8161047f602093836117b1565b81010312610490576020905161045a565b600080fd5b3d9150610472565b604051903d90823e3d90fd5b50346101f157806003193601126101f1576040517f000000000000000000000000683035188e3670fda1def2a7aa5742dea28ed5f36001600160a01b03168152602090f35b50346101f15760203660031901126101f157600435610538337f000000000000000000000000683035188e3670fda1def2a7aa5742dea28ed5f36001600160a01b03168114611801565b80600c5403610545575080f35b6020817f6001f93d1361f13fa994a862c252794b9526d07cb0e34c9fe2e01c4c17e7319d92600c55604051908152a180f35b50346101f157806003193601126101f1576020600a54604051908152f35b50346101f157806003193601126101f1576105ae611894565b6105e3337f0000000000000000000000000b6d3b42861ee8abfcaac818033694e758ecc3eb6001600160a01b03168114611801565b604051631ed2419560e01b81526020816004817f000000000000000000000000942117ec0458a8aa08669e94b52001bd43f889c16001600160a01b03165afa908115610754578291610799575b50600a5481118061078b575b610644575080f35b600a55600b80549082905560405163095ea7b360e01b81527f000000000000000000000000edd7cbc9c47547d0b552d5bc2be76135f49c15b16001600160a01b0381166004830152602482018390529192919060208180604481010381867f000000000000000000000000efd81eec32b9a8222d1842ec3d99c7532c31e3486001600160a01b03165af1801561078057610763575b506001600160a01b0316803b1561075f57818091602460405180948193633c6b16ab60e01b83528860048401525af1801561075457610744575b50906040519081527fcf0cf43969b3f0a08a20481cfa1fd31d1023ab827f0babb8d8125862a9c403f860203392a280f35b8161074e916117b1565b38610713565b6040513d84823e3d90fd5b5080fd5b61077b9060203d6020116103d5576103c681836117b1565b6106d9565b6040513d85823e3d90fd5b50600b54600c54111561063c565b90506020813d6020116107c3575b816107b4602093836117b1565b8101031261075f575138610630565b3d91506107a7565b50346101f15760203660031901126101f1576020906040906001600160a01b036107f3611702565b1681526007835220541515604051908152f35b50346101f15760403660031901126101f15761082d610823611702565b60243590336118b1565b602060405160018152f35b50346101f157806003193601126101f1576040519080600454908160011c91600181168015610937575b602084108114610923578386529081156108fc575060011461089f575b61089b8461088f818603826117b1565b604051918291826116b9565b0390f35b600481527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b939250905b8082106108e25750909150810160200161088f8261087f565b9192600181602092548385880101520191019092916108c9565b60ff191660208087019190915292151560051b8501909201925061088f915083905061087f565b634e487b7160e01b83526022600452602483fd5b92607f1692610862565b50346101f1576109503661175f565b91929091610989337f000000000000000000000000683035188e3670fda1def2a7aa5742dea28ed5f36001600160a01b03168114611801565b808403610a5a57845b81811061099d578580f35b806109b36109ae600193858861182a565b611850565b15610a38576109d5828060a01b036109cf61031c848a8961182a565b16611f05565b7f0c26de26c21d52b9af1eae2bc6d3c4f03cf66cf139d32166af29b8aed7135192610a0461031c848a8961182a565b91610a136109ae85888b61182a565b604080519115158252911515602082015260a086901b8690039390931692a201610992565b610a55828060a01b03610a4f61031c848a8961182a565b16611df6565b6109d5565b630f40213560e21b8552600485fd5b50346101f157806003193601126101f1576020600b54604051908152f35b50346101f157806003193601126101f1576040517f000000000000000000000000942117ec0458a8aa08669e94b52001bd43f889c16001600160a01b03168152602090f35b50346101f157806003193601126101f157610b12337f000000000000000000000000683035188e3670fda1def2a7aa5742dea28ed5f36001600160a01b03168114611801565b610b1a611894565b600160ff1960055416176005557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a180f35b50346101f15760203660031901126101f157600435610b71611894565b8015610c86576207a12081028181046207a12003610c7257620f4240900480820391808311610c5e5790610ba8610bb09233611aee565b600b54611871565b600b5560405163a9059cbb60e01b815233600482015260248101829052602081604481866001600160a01b037f000000000000000000000000efd81eec32b9a8222d1842ec3d99c7532c31e348165af180156107805760209350610c43575b506040518181527fa8a63b0531e55ae709827fb089d01034e24a200ad14dc710dfa9e962005f629a833392a2604051908152f35b610c5990833d85116103d5576103c681836117b1565b610c0f565b634e487b7160e01b84526011600452602484fd5b634e487b7160e01b83526011600452602483fd5b632c7d31e560e11b8252600482fd5b50346101f157806003193601126101f1576040517f000000000000000000000000edd7cbc9c47547d0b552d5bc2be76135f49c15b16001600160a01b03168152602090f35b50346101f15760203660031901126101f1576020906040906001600160a01b03610d02611702565b1681528083522054604051908152f35b50346101f15760203660031901126101f157610d2c611702565b610d61337f000000000000000000000000683035188e3670fda1def2a7aa5742dea28ed5f36001600160a01b03168114611801565b600554906001600160a01b0380821690600884901c16818114610dc6577ff1e04d73c4304b5ff164f9d10c7473e2a1593b740674a6107975e2a7001c1e5c8580a3610100600160a81b031990911660089190911b610100600160a81b03161760055580f35b600162067eab60e51b03198552600485fd5b50346101f157806003193601126101f157602060ff600554166040519015158152f35b50346101f157806003193601126101f15760055460405160089190911c6001600160a01b03168152602090f35b50346101f157806003193601126101f1576020600c54604051908152f35b50346101f157806003193601126101f1576020604051620f42408152f35b50346101f157806003193601126101f1576040517f000000000000000000000000efd81eec32b9a8222d1842ec3d99c7532c31e3486001600160a01b03168152602090f35b50346101f157806003193601126101f157610eef337f000000000000000000000000683035188e3670fda1def2a7aa5742dea28ed5f36001600160a01b03168114611801565b60055460ff811615610f2f5760ff19166005557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a180f35b638dfc202b60e01b8252600482fd5b50346101f157610f4d3661175f565b91929091610f86337f000000000000000000000000683035188e3670fda1def2a7aa5742dea28ed5f36001600160a01b03168114611801565b808403610a5a57845b818110610f9a578580f35b80610fab6109ae600193858861182a565b1561103057610fcd828060a01b03610fc761031c848a8961182a565b16611eaa565b7f0c26de26c21d52b9af1eae2bc6d3c4f03cf66cf139d32166af29b8aed7135192610ffc61031c848a8961182a565b9161100b6109ae85888b61182a565b604080519115158252911515602082015260a086901b8690039390931692a201610f8f565b61104d828060a01b0361104761031c848a8961182a565b16611d0e565b610fcd565b50346101f15760203660031901126101f15760043561109c337f000000000000000000000000683035188e3670fda1def2a7aa5742dea28ed5f36001600160a01b03168114611801565b6005546110b690829060081c6001600160a01b0316611aee565b60055460405163a9059cbb60e01b815260089190911c6001600160a01b031660048201526024810182905260208180604481010381867f000000000000000000000000efd81eec32b9a8222d1842ec3d99c7532c31e3486001600160a01b03165af1801561078057611153575b506040519081527fcdbac541db49fbbf60d76d4efac473eebe6a9b957ace755163cbdf13f03515eb60203092a280f35b61116b9060203d6020116103d5576103c681836117b1565b611123565b50346101f157806003193601126101f157602060405160128152f35b50346101f157806003193601126101f15760206040516207a1208152f35b50346101f15760603660031901126101f1576111c4611702565b6111cc611718565b6001600160a01b038216808452600160208181526040808720338852909152852054604435949290918201611208575b505061082d93506118b1565b84821061126f57801561125b57331561124757604086869261082d9852600160205281812060018060a01b0333168252602052209103905538806111fc565b634a1406b160e11b86526004869052602486fd5b63e602df0560e01b86526004869052602486fd5b6064868684637dc7a0d960e11b835233600452602452604452fd5b50346101f157806003193601126101f1576020600254604051908152f35b50346101f15760203660031901126101f1576004356112c5611894565b8015610c86576040516323b872dd60e01b815233600482015230602482015260448101829052602081606481867f000000000000000000000000efd81eec32b9a8222d1842ec3d99c7532c31e3486001600160a01b03165af1801561078057611539575b5033156115255781828052600760205260408320541580159061151d575b8015611516575b8015611501575b156113f75750600160ff815b16036113e35761137381600254611871565b6002553382528160205260408220818154019055604051818152827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60203393a36040519081527fa428517b481b65176e7c35a57b564d5cf943c8462468b8a0f025fa689173f90160203392a280f35b630b7b234960e01b82526004829052602482fd5b60405163aa79979b60e01b8152600481018490527f000000000000000000000000942117ec0458a8aa08669e94b52001bd43f889c16001600160a01b0316602082602481845afa9182156114f65785926114d5575b508115611476575b50611464575b60ff600191611361565b5061146e82611f05565b50600161145a565b6024915060209060405192838092635397401b60e01b82528860048301525afa9081156114ca5784916114ab575b5038611454565b6114c4915060203d6020116103d5576103c681836117b1565b386114a4565b6040513d86823e3d90fd5b6114ef91925060203d6020116103d5576103c681836117b1565b903861144c565b6040513d87823e3d90fd5b50338352600960205260408320541515611355565b508261134e565b506001611347565b63ec442f0560e01b82526004829052602482fd5b6115519060203d6020116103d5576103c681836117b1565b611329565b50346101f15760403660031901126101f157611570611702565b6024359033156115ec576001600160a01b03169182156115d85760408291338152600160205281812085825260205220556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b634a1406b160e11b81526004819052602490fd5b63e602df0560e01b83526004839052602483fd5b82346101f157806003193601126101f15780600354908160011c916001811680156116af575b602084108114610923578386529081156108fc57506001146116525761089b8461088f818603826117b1565b600381527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b939250905b8082106116955750909150810160200161088f8261087f565b91926001816020925483858801015201910190929161167c565b92607f1692611626565b91909160208152825180602083015260005b8181106116ec575060409293506000838284010152601f8019910116010190565b80602080928701015160408286010152016116cb565b600435906001600160a01b038216820361049057565b602435906001600160a01b038216820361049057565b9181601f840112156104905782359167ffffffffffffffff8311610490576020808501948460051b01011161049057565b60406003198201126104905760043567ffffffffffffffff8111610490578161178a9160040161172e565b929092916024359067ffffffffffffffff8211610490576117ad9160040161172e565b9091565b90601f8019910116810190811067ffffffffffffffff8211176117d357604052565b634e487b7160e01b600052604160045260246000fd5b90816020910312610490575180151581036104905790565b156118095750565b632bc10c3360e01b60009081526001600160a01b0391909116600452602490fd5b919081101561183a5760051b0190565b634e487b7160e01b600052603260045260246000fd5b3580151581036104905790565b356001600160a01b03811681036104905790565b9190820180921161187e57565b634e487b7160e01b600052601160045260246000fd5b60ff600554166118a057565b63d93c066560e01b60005260046000fd5b6001600160a01b0316908115611ad8576001600160a01b0316918215611ac257600082600052600760205260406000205415801590611aba575b8015611ab2575b8015611a9b575b156119995750600160ff815b160361198457600082815280602052604081205482811061196a5791604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef958760209652828652038282205586815280845220818154019055604051908152a3565b916064928463391434e360e21b8452600452602452604452fd5b50630b7b234960e01b60005260045260246000fd5b60405163aa79979b60e01b8152600481018490527f000000000000000000000000942117ec0458a8aa08669e94b52001bd43f889c16001600160a01b0316602082602481845afa918215611a6e57600092611a7a575b508115611a19575b50611a07575b60ff600191611905565b50611a1182611f05565b5060016119fd565b6024915060209060405192838092635397401b60e01b82528860048301525afa908115611a6e57600091611a4f575b50386119f7565b611a68915060203d6020116103d5576103c681836117b1565b38611a48565b6040513d6000823e3d90fd5b611a9491925060203d6020116103d5576103c681836117b1565b90386119ef565b5083600052600960205260406000205415156118f9565b5060006118f2565b5060006118eb565b63ec442f0560e01b600052600060045260246000fd5b634b637e8f60e11b600052600060045260246000fd5b6001600160a01b03168015611ad857600081600052600760205260406000205415801590611cee575b8015611ce6575b8015611cb3575b15611bbd5750600160ff815b1603611ba957600091818352826020526040832054818110611b9057817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef926020928587528684520360408620558060025403600255604051908152a3565b6064939263391434e360e21b8452600452602452604452fd5b630b7b234960e01b60005260045260246000fd5b60405163aa79979b60e01b8152600481018390527f000000000000000000000000942117ec0458a8aa08669e94b52001bd43f889c16001600160a01b0316602082602481845afa918215611a6e57600092611c92575b508115611c3d575b50611c2b575b60ff600191611b31565b50611c3581611f05565b506001611c21565b6024915060209060405192838092635397401b60e01b82528760048301525afa908115611a6e57600091611c73575b5038611c1b565b611c8c915060203d6020116103d5576103c681836117b1565b38611c6c565b611cac91925060203d6020116103d5576103c681836117b1565b9038611c13565b506000805260096020527fec8156718a8372b1db44bb411437d0870f3e3790d4a08526d024ce1b0b668f6b541515611b25565b506001611b1e565b506000611b17565b805482101561183a5760005260206000200190600090565b6000818152600960205260409020548015611def57600019810181811161187e5760085460001981019190821161187e57818103611d9e575b5050506008548015611d885760001901611d62816008611cf6565b8154906000199060031b1b19169055600855600052600960205260006040812055600190565b634e487b7160e01b600052603160045260246000fd5b611dd7611daf611dc0936008611cf6565b90549060031b1c9283926008611cf6565b819391549060031b91821b91600019901b19161790565b90556000526009602052604060002055388080611d47565b5050600090565b6000818152600760205260409020548015611def57600019810181811161187e5760065460001981019190821161187e57818103611e70575b5050506006548015611d885760001901611e4a816006611cf6565b8154906000199060031b1b19169055600655600052600760205260006040812055600190565b611e92611e81611dc0936006611cf6565b90549060031b1c9283926006611cf6565b90556000526007602052604060002055388080611e2f565b80600052600960205260406000205415600014611eff57600854600160401b8110156117d357611ee6611dc08260018594016008556008611cf6565b9055600854906000526009602052604060002055600190565b50600090565b80600052600760205260406000205415600014611eff57600654600160401b8110156117d357611f41611dc08260018594016006556006611cf6565b905560065490600052600760205260406000205560019056fea2646970667358221220f61b9dc53cc7078a147067df79cc354fcd7f0a22e705dcac5c011c091cb7631a64736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000efd81eec32b9a8222d1842ec3d99c7532c31e348000000000000000000000000942117ec0458a8aa08669e94b52001bd43f889c1000000000000000000000000de4b22eb9f9c2c55e72e330c87663b28e9d388f7000000000000000000000000683035188e3670fda1def2a7aa5742dea28ed5f3000000000000000000000000edd7cbc9c47547d0b552d5bc2be76135f49c15b10000000000000000000000000b6d3b42861ee8abfcaac818033694e758ecc3eb
-----Decoded View---------------
Arg [0] : _rex (address): 0xEfD81eeC32B9A8222D1842ec3d99c7532C31e348
Arg [1] : _voter (address): 0x942117Ec0458a8AA08669E94B52001Bd43F889C1
Arg [2] : _operator (address): 0xde4B22Eb9F9c2C55e72e330C87663b28e9d388f7
Arg [3] : _accessHub (address): 0x683035188E3670fda1deF2a7Aa5742DEa28Ed5f3
Arg [4] : _voteModule (address): 0xedD7cbc9C47547D0b552d5Bc2BE76135f49C15b1
Arg [5] : _minter (address): 0x0b6d3B42861eE8aBFCaaC818033694E758ECC3eb
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 000000000000000000000000efd81eec32b9a8222d1842ec3d99c7532c31e348
Arg [1] : 000000000000000000000000942117ec0458a8aa08669e94b52001bd43f889c1
Arg [2] : 000000000000000000000000de4b22eb9f9c2c55e72e330c87663b28e9d388f7
Arg [3] : 000000000000000000000000683035188e3670fda1def2a7aa5742dea28ed5f3
Arg [4] : 000000000000000000000000edd7cbc9c47547d0b552d5bc2be76135f49c15b1
Arg [5] : 0000000000000000000000000b6d3b42861ee8abfcaac818033694e758ecc3eb
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.
Add Token to MetaMask (Web3)