More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
ShadowTreasury
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 333 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IXShadow} from "contracts/interfaces/IXShadow.sol"; import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; import {IAccessHub} from "contracts/interfaces/IAccessHub.sol"; import {IVoteModule} from "contracts/interfaces/IVoteModule.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IVoter} from "contracts/interfaces/IVoter.sol"; import {Initializable} from "@openzeppelin-contracts-upgradeable/proxy/utils/Initializable.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; contract ShadowTreasury is Initializable, ReentrancyGuard { using EnumerableMap for EnumerableMap.AddressToUintMap; /// @dev ERRORS // authorization errors error NotTimelock(address caller); error NotTreasury(address caller); error NotOperator(address caller); error NotMember(address account); // input validation errors error InvalidAddress(); error InvalidWeight(uint256 weight); error InvalidTotalWeight(uint256 total); error ZeroAddress(); error ZeroAmount(); // state errors error InvalidAggregator(address aggregator); error NoMembers(); error NoBalance(); error WARNING(); // transaction errors error TransferFailed(); error CallFailed(); error AggregatorFailed(bytes returnData); /// @dev STATE // globals IXShadow public xShadow; IVoteModule public voteModule; address public treasury; address public timelock; IVoter public voter; address public operator; // config mapping(address => bool) public whitelistedAggregators; EnumerableMap.AddressToUintMap private memberWeights; uint256 public totalWeight; uint256 private constant BASIS_POINTS = 1_000_000; /// @dev STRUCTS struct AggregatorParams { address _aggregator; address _tokenIn; uint256 _amountIn; uint256 _minAmountOut; bytes _callData; } /// @dev EVENTS event MemberUpdated(address account, uint256 weight); event Distribution(address indexed member, address indexed token, uint256 amount); event AggregatorWhitelistUpdated(address aggregator, bool status); constructor() { _disableInitializers(); } function initialize(IXShadow _xShadow, address _initialOperator) public initializer { if (address(_xShadow) == address(0)) revert ZeroAddress(); if (_initialOperator == address(0)) revert ZeroAddress(); xShadow = _xShadow; IAccessHub accessHub = IAccessHub(xShadow.ACCESS_HUB()); timelock = accessHub.timelock(); treasury = accessHub.treasury(); voteModule = IVoteModule(accessHub.voteModule()); voter = IVoter(accessHub.voter()); operator = _initialOperator; // members _updateMember(0x5EbB8663b9d213026aD9776dbA264c3Ef1A40f37, 100000); _updateMember(0x9E9f5bf31B1b5387Ea65f5b955fA0DA0eD6f23ea, 100000); _updateMember(0x5E363a8c41eBDCbcb32DC488eE610Ee6580B1f8f, 100000); _updateMember(0x796BE2312E5C086640C67493eC01852300c4136B, 90000); _updateMember(0xCAfc58De1E6A071790eFbB6B83b35397023E1544, 90000); _updateMember(0x6279bd15156592d1C744c3293145b9F9d0cb0051, 90000); _updateMember(0xB3bfB32977cFd6200AB9537E3703e501d8381c9B, 100000); _updateMember(0xb9eb10BA936F35D5BdcCa9B1CF477d6b152ABfeD, 100000); _updateMember(0x031F72dEB03C509af42624ddcD1f63fce5eCb220, 80000); _updateMember(0x2860cE83720bAB73B28E0179F64F2EAF810fD995, 70000); _updateMember(0xEC26DE1b53436b959E534287888a297066cdd37D, 60000); _updateMember(0xcE191069f6bEa7f9BBbAF1fD73Fd3Cd4DbeFB8c0, 20000); // odos _whitelistAggregator(0xaC041Df48dF9791B0654f1Dbbf2CC8450C5f2e9D, true); } function _updateMember(address _account, uint256 _weight) internal { if (_account == address(0)) revert InvalidAddress(); if (_weight > BASIS_POINTS) revert InvalidWeight(_weight); if (memberWeights.contains(_account)) { uint256 oldWeight = memberWeights.get(_account); totalWeight -= oldWeight; } totalWeight += _weight; if (totalWeight > BASIS_POINTS) revert InvalidTotalWeight(totalWeight); if (_weight > 0) { memberWeights.set(_account, _weight); } else { memberWeights.remove(_account); } emit MemberUpdated(_account, _weight); } function _whitelistAggregator(address _aggregator, bool _status) internal { whitelistedAggregators[_aggregator] = _status; emit AggregatorWhitelistUpdated(_aggregator, _status); } function updateMember(address _account, uint256 _weight) external onlyTreasury { _updateMember(_account, _weight); } function whitelistAggregator(address _aggregator, bool _status) external onlyTimelock { _whitelistAggregator(_aggregator, _status); } /// @dev MODIFIERS modifier onlyTimelock() { if (msg.sender != timelock) revert NotTimelock(msg.sender); _; } modifier onlyTreasury() { if (msg.sender != treasury) revert NotTreasury(msg.sender); _; } modifier onlyOperator() { if (msg.sender != operator) revert NotOperator(msg.sender); _; } /// @dev MANAGEMENT function updateOperator(address _newOperator) external onlyTimelock { if (_newOperator == address(0)) revert ZeroAddress(); operator = _newOperator; } /// @dev TREASURY OPERATIONS function depositXShadow(uint256 _amount) external onlyTreasury { if (_amount == 0) revert ZeroAmount(); xShadow.transferFrom(msg.sender, address(this), _amount); xShadow.approve(address(voteModule), _amount); voteModule.deposit(_amount); } function withdrawXShadow(uint256 _amount) external onlyTreasury { if (_amount == 0) revert ZeroAmount(); voteModule.withdraw(_amount); xShadow.transfer(msg.sender, _amount); } /// @dev OPERATOR UPKEEP function claimRebase() external onlyOperator { voteModule.earned(address(this)); voteModule.getReward(); voteModule.depositAll(); } function claimIncentives(address[] calldata _feeDistributors, address[][] calldata _tokens) external onlyOperator { voter.claimIncentives(address(this), _feeDistributors, _tokens); } function swapIncentiveViaAggregator(AggregatorParams calldata _params) external nonReentrant onlyOperator { if (!whitelistedAggregators[_params._aggregator]) revert InvalidAggregator(_params._aggregator); // snapshot the staked xshadow to protect it uint256 stakedBalanceBefore = voteModule.balanceOf(address(this)); // swap via aggregator IERC20(_params._tokenIn).approve(_params._aggregator, _params._amountIn); (bool success, bytes memory returnData) = _params._aggregator.call(_params._callData); if (!success) revert AggregatorFailed(returnData); // validate snapshot uint256 stakedBalanceAfter = voteModule.balanceOf(address(this)); if (stakedBalanceAfter < stakedBalanceBefore) revert WARNING(); } function distribute(address _token) external onlyOperator { if (memberWeights.length() == 0) revert NoMembers(); if (_token == address(0)) revert ZeroAddress(); uint256 balance = IERC20(_token).balanceOf(address(this)); if (balance == 0) revert NoBalance(); for (uint256 i = 0; i < memberWeights.length(); i++) { (address account, uint256 weight) = memberWeights.at(i); uint256 share = (balance * weight) / BASIS_POINTS; if (share > 0) { bool success = IERC20(_token).transfer(account, share); if (!success) revert TransferFailed(); emit Distribution(account, _token, share); } } } /// @dev VIEW FUNCTIONS function getMemberWeight(address _account) external view returns (uint256) { require(memberWeights.contains(_account), NotMember(_account)); return memberWeights.get(_account); } function getMemberCount() external view returns (uint256) { return memberWeights.length(); } function getAllMembers() external view returns (address[] memory accounts, uint256[] memory weights) { uint256 length = memberWeights.length(); accounts = new address[](length); weights = new uint256[](length); for (uint256 i = 0; i < length; i++) { (accounts[i], weights[i]) = memberWeights.at(i); } return (accounts, weights); } function treasuryVotingPower() external view returns (uint256) { uint256 totalVotingPower = voteModule.balanceOf(address(this)) + xShadow.balanceOf(address(this)) + voteModule.earned(address(this)); uint256 totalSupply = xShadow.totalSupply(); return totalVotingPower * 1e18 / totalSupply; } /// @dev SAFETY FUNCTIONS function recoverERC20(address _token, uint256 _amount) external nonReentrant onlyTreasury { IERC20(_token).transfer(treasury, _amount); } function recoverNative() external nonReentrant onlyTreasury { (bool success,) = treasury.call{value: address(this).balance}(""); if (!success) revert TransferFailed(); } function emergencyExecute(address _to, bytes calldata _data) external nonReentrant onlyTimelock { if (_to == address(0)) revert ZeroAddress(); (bool success,) = _to.call(_data); if (!success) revert CallFailed(); } }
// 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 IXShadow is IERC20 { struct VestPosition { /// @dev amount of xShadow uint256 amount; /// @dev start unix timestamp uint256 start; /// @dev start + MAX_VEST (end timestamp) uint256 maxEnd; /// @dev vest identifier (starting from 0) uint256 vestID; } event CancelVesting(address indexed user, uint256 indexed vestId, uint256 amount); event ExitVesting(address indexed user, uint256 indexed vestId, uint256 amount); event InstantExit(address indexed user, uint256); event NewSlashingPenalty(uint256 penalty); event NewVest(address indexed user, uint256 indexed vestId, uint256 indexed amount); event NewVestingTimes(uint256 min, uint256 max); event Converted(address indexed user, uint256); event Exemption(address indexed candidate, bool status, bool success); event XShadowRedeemed(address indexed user, uint256); event NewOperator(address indexed o, address indexed n); event Rebase(address indexed caller, uint256 amount); event NewRebaseThreshold(uint256 threshold); /// @notice returns info on a user's vests function vestInfo(address user, uint256) external view returns (uint256 amount, uint256 start, uint256 maxEnd, uint256 vestID); /// @notice address of the shadow token function SHADOW() 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); /// @notice the minimum vesting length function MIN_VEST() external view returns (uint256); /// @notice the maximum vesting length function MAX_VEST() external view returns (uint256); function shadow() 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 xShadows for each shadow. 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 xShadows to exit */ function exit(uint256 _amount) external returns (uint256 _exitedAmount); /// @dev vesting xShadows --> emissionToken functionality function createVest(uint256 _amount) external; /// @dev handles all situations regarding exiting vests function exitVest(uint256 _vestID) external; /** * */ // Permissioned functions, timelock/operator gated /** * */ /// @dev allows the operator to redeem collected xShadows 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 SHADOW within the contract function getBalanceResiding() external view returns (uint256); /// @notice returns the total number of individual vests the user has function usersTotalVests(address _who) external view returns (uint256 _numOfVests); /// @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 returns the vest info for a user /// @param _who who to check /// @param _vestID vest ID to check /// @return VestPosition vest info function getVestInfo(address _who, uint256 _vestID) external view returns (VestPosition memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/structs/EnumerableMap.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableMap.js. pragma solidity ^0.8.20; import {EnumerableSet} from "./EnumerableSet.sol"; /** * @dev Library for managing an enumerable variant of Solidity's * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] * type. * * Maps have the following properties: * * - Entries are added, removed, and checked for existence in constant time * (O(1)). * - Entries are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableMap for EnumerableMap.UintToAddressMap; * * // Declare a set state variable * EnumerableMap.UintToAddressMap private myMap; * } * ``` * * The following map types are supported: * * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0 * - `address -> uint256` (`AddressToUintMap`) since v4.6.0 * - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0 * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0 * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0 * - `uint256 -> bytes32` (`UintToBytes32Map`) since v5.1.0 * - `address -> address` (`AddressToAddressMap`) since v5.1.0 * - `address -> bytes32` (`AddressToBytes32Map`) since v5.1.0 * - `bytes32 -> address` (`Bytes32ToAddressMap`) since v5.1.0 * * [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 EnumerableMap, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableMap. * ==== */ library EnumerableMap { using EnumerableSet for EnumerableSet.Bytes32Set; // To implement this library for multiple types with as little code repetition as possible, we write it in // terms of a generic Map type with bytes32 keys and values. The Map implementation uses private functions, // and user-facing implementations such as `UintToAddressMap` are just wrappers around the underlying Map. // This means that we can only create new EnumerableMaps for types that fit in bytes32. /** * @dev Query for a nonexistent map key. */ error EnumerableMapNonexistentKey(bytes32 key); struct Bytes32ToBytes32Map { // Storage of keys EnumerableSet.Bytes32Set _keys; mapping(bytes32 key => bytes32) _values; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value) internal returns (bool) { map._values[key] = value; return map._keys.add(key); } /** * @dev Removes a key-value pair from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) { delete map._values[key]; return map._keys.remove(key); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) { return map._keys.contains(key); } /** * @dev Returns the number of key-value pairs in the map. O(1). */ function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) { return map._keys.length(); } /** * @dev Returns the key-value pair stored at position `index` in the map. O(1). * * Note that there are no guarantees on the ordering of entries inside the * array, and it may change when more entries are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32 key, bytes32 value) { bytes32 atKey = map._keys.at(index); return (atKey, map._values[atKey]); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool exists, bytes32 value) { bytes32 val = map._values[key]; if (val == bytes32(0)) { return (contains(map, key), bytes32(0)); } else { return (true, val); } } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) { bytes32 value = map._values[key]; if (value == 0 && !contains(map, key)) { revert EnumerableMapNonexistentKey(key); } return value; } /** * @dev Return the an array containing all the keys * * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. */ function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) { return map._keys.values(); } // UintToUintMap struct UintToUintMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(UintToUintMap storage map, uint256 key, uint256 value) internal returns (bool) { return set(map._inner, bytes32(key), bytes32(value)); } /** * @dev Removes a value from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToUintMap storage map, uint256 key) internal returns (bool) { return remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) { return contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToUintMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the map. 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(UintToUintMap storage map, uint256 index) internal view returns (uint256 key, uint256 value) { (bytes32 atKey, bytes32 val) = at(map._inner, index); return (uint256(atKey), uint256(val)); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool exists, uint256 value) { (bool success, bytes32 val) = tryGet(map._inner, bytes32(key)); return (success, uint256(val)); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) { return uint256(get(map._inner, bytes32(key))); } /** * @dev Return the an array containing all the keys * * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. */ function keys(UintToUintMap storage map) internal view returns (uint256[] memory) { bytes32[] memory store = keys(map._inner); uint256[] memory result; assembly ("memory-safe") { result := store } return result; } // UintToAddressMap struct UintToAddressMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) { return set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { return remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { return contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToAddressMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the map. 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(UintToAddressMap storage map, uint256 index) internal view returns (uint256 key, address value) { (bytes32 atKey, bytes32 val) = at(map._inner, index); return (uint256(atKey), address(uint160(uint256(val)))); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool exists, address value) { (bool success, bytes32 val) = tryGet(map._inner, bytes32(key)); return (success, address(uint160(uint256(val)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { return address(uint160(uint256(get(map._inner, bytes32(key))))); } /** * @dev Return the an array containing all the keys * * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. */ function keys(UintToAddressMap storage map) internal view returns (uint256[] memory) { bytes32[] memory store = keys(map._inner); uint256[] memory result; assembly ("memory-safe") { result := store } return result; } // UintToBytes32Map struct UintToBytes32Map { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(UintToBytes32Map storage map, uint256 key, bytes32 value) internal returns (bool) { return set(map._inner, bytes32(key), value); } /** * @dev Removes a value from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToBytes32Map storage map, uint256 key) internal returns (bool) { return remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToBytes32Map storage map, uint256 key) internal view returns (bool) { return contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToBytes32Map storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the map. 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(UintToBytes32Map storage map, uint256 index) internal view returns (uint256 key, bytes32 value) { (bytes32 atKey, bytes32 val) = at(map._inner, index); return (uint256(atKey), val); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(UintToBytes32Map storage map, uint256 key) internal view returns (bool exists, bytes32 value) { (bool success, bytes32 val) = tryGet(map._inner, bytes32(key)); return (success, val); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToBytes32Map storage map, uint256 key) internal view returns (bytes32) { return get(map._inner, bytes32(key)); } /** * @dev Return the an array containing all the keys * * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. */ function keys(UintToBytes32Map storage map) internal view returns (uint256[] memory) { bytes32[] memory store = keys(map._inner); uint256[] memory result; assembly ("memory-safe") { result := store } return result; } // AddressToUintMap struct AddressToUintMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(AddressToUintMap storage map, address key, uint256 value) internal returns (bool) { return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value)); } /** * @dev Removes a value from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(AddressToUintMap storage map, address key) internal returns (bool) { return remove(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(AddressToUintMap storage map, address key) internal view returns (bool) { return contains(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns the number of elements in the map. O(1). */ function length(AddressToUintMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the map. 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(AddressToUintMap storage map, uint256 index) internal view returns (address key, uint256 value) { (bytes32 atKey, bytes32 val) = at(map._inner, index); return (address(uint160(uint256(atKey))), uint256(val)); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(AddressToUintMap storage map, address key) internal view returns (bool exists, uint256 value) { (bool success, bytes32 val) = tryGet(map._inner, bytes32(uint256(uint160(key)))); return (success, uint256(val)); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(AddressToUintMap storage map, address key) internal view returns (uint256) { return uint256(get(map._inner, bytes32(uint256(uint160(key))))); } /** * @dev Return the an array containing all the keys * * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. */ function keys(AddressToUintMap storage map) internal view returns (address[] memory) { bytes32[] memory store = keys(map._inner); address[] memory result; assembly ("memory-safe") { result := store } return result; } // AddressToAddressMap struct AddressToAddressMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(AddressToAddressMap storage map, address key, address value) internal returns (bool) { return set(map._inner, bytes32(uint256(uint160(key))), bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(AddressToAddressMap storage map, address key) internal returns (bool) { return remove(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(AddressToAddressMap storage map, address key) internal view returns (bool) { return contains(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns the number of elements in the map. O(1). */ function length(AddressToAddressMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the map. 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(AddressToAddressMap storage map, uint256 index) internal view returns (address key, address value) { (bytes32 atKey, bytes32 val) = at(map._inner, index); return (address(uint160(uint256(atKey))), address(uint160(uint256(val)))); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(AddressToAddressMap storage map, address key) internal view returns (bool exists, address value) { (bool success, bytes32 val) = tryGet(map._inner, bytes32(uint256(uint160(key)))); return (success, address(uint160(uint256(val)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(AddressToAddressMap storage map, address key) internal view returns (address) { return address(uint160(uint256(get(map._inner, bytes32(uint256(uint160(key))))))); } /** * @dev Return the an array containing all the keys * * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. */ function keys(AddressToAddressMap storage map) internal view returns (address[] memory) { bytes32[] memory store = keys(map._inner); address[] memory result; assembly ("memory-safe") { result := store } return result; } // AddressToBytes32Map struct AddressToBytes32Map { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(AddressToBytes32Map storage map, address key, bytes32 value) internal returns (bool) { return set(map._inner, bytes32(uint256(uint160(key))), value); } /** * @dev Removes a value from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(AddressToBytes32Map storage map, address key) internal returns (bool) { return remove(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(AddressToBytes32Map storage map, address key) internal view returns (bool) { return contains(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns the number of elements in the map. O(1). */ function length(AddressToBytes32Map storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the map. 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(AddressToBytes32Map storage map, uint256 index) internal view returns (address key, bytes32 value) { (bytes32 atKey, bytes32 val) = at(map._inner, index); return (address(uint160(uint256(atKey))), val); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(AddressToBytes32Map storage map, address key) internal view returns (bool exists, bytes32 value) { (bool success, bytes32 val) = tryGet(map._inner, bytes32(uint256(uint160(key)))); return (success, val); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(AddressToBytes32Map storage map, address key) internal view returns (bytes32) { return get(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Return the an array containing all the keys * * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. */ function keys(AddressToBytes32Map storage map) internal view returns (address[] memory) { bytes32[] memory store = keys(map._inner); address[] memory result; assembly ("memory-safe") { result := store } return result; } // Bytes32ToUintMap struct Bytes32ToUintMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(Bytes32ToUintMap storage map, bytes32 key, uint256 value) internal returns (bool) { return set(map._inner, key, bytes32(value)); } /** * @dev Removes a value from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) { return remove(map._inner, key); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) { return contains(map._inner, key); } /** * @dev Returns the number of elements in the map. O(1). */ function length(Bytes32ToUintMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the map. 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(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32 key, uint256 value) { (bytes32 atKey, bytes32 val) = at(map._inner, index); return (atKey, uint256(val)); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool exists, uint256 value) { (bool success, bytes32 val) = tryGet(map._inner, key); return (success, uint256(val)); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) { return uint256(get(map._inner, key)); } /** * @dev Return the an array containing all the keys * * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. */ function keys(Bytes32ToUintMap storage map) internal view returns (bytes32[] memory) { bytes32[] memory store = keys(map._inner); bytes32[] memory result; assembly ("memory-safe") { result := store } return result; } // Bytes32ToAddressMap struct Bytes32ToAddressMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(Bytes32ToAddressMap storage map, bytes32 key, address value) internal returns (bool) { return set(map._inner, key, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(Bytes32ToAddressMap storage map, bytes32 key) internal returns (bool) { return remove(map._inner, key); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (bool) { return contains(map._inner, key); } /** * @dev Returns the number of elements in the map. O(1). */ function length(Bytes32ToAddressMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the map. 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(Bytes32ToAddressMap storage map, uint256 index) internal view returns (bytes32 key, address value) { (bytes32 atKey, bytes32 val) = at(map._inner, index); return (atKey, address(uint160(uint256(val)))); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (bool exists, address value) { (bool success, bytes32 val) = tryGet(map._inner, key); return (success, address(uint160(uint256(val)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (address) { return address(uint160(uint256(get(map._inner, key)))); } /** * @dev Return the an array containing all the keys * * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. */ function keys(Bytes32ToAddressMap storage map) internal view returns (bytes32[] memory) { bytes32[] memory store = keys(map._inner); bytes32[] memory result; assembly ("memory-safe") { result := store } return result; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IAccessControlEnumerable} from "@openzeppelin/contracts/access/extensions/IAccessControlEnumerable.sol"; import {IVoteModule} from "contracts/interfaces/IVoteModule.sol"; import {IVoter} from "contracts/interfaces/IVoter.sol"; interface IAccessHub0 { /// @dev Struct to hold initialization parameters struct InitParams { address timelock; address treasury; address voter; address minter; address launcherPlugin; address xShadow; address x33; address shadowV3PoolFactory; address poolFactory; address clGaugeFactory; address gaugeFactory; address feeRecipientFactory; address feeDistributorFactory; address feeCollector; address voteModule; address x33Adapter; } /// @notice initializing function for setting values in the AccessHub function initialize(InitParams calldata params) external; /// @notice function for reinitializing values in the AccessHub function reinit(InitParams calldata params) external; /// @notice function for adding expansion packs to AccessHub function registerExpansionPack(address _newExpansionPack) external; /// @notice function for replacing an expansion pack on AccessHub function replaceExpansionPack(address _oldExpansionPack, address _newExpansionPack) external; /// @notice function for removing expansion packs from AccessHub function removeExpansionPack(address _expansionPack) external; /// @notice returns all expansion packs function getAllExpansionPacks() external view returns (address[] memory); /// @notice returns expansion pack length function getAllExpansionPackLength() external view returns (uint256); /// @notice returns expansion pack at index function getExpansionPack(uint256 index) external view returns (address); /// @notice sets the swap fees for multiple pairs function setSwapFees(address[] calldata _pools, uint24[] calldata _swapFees, bool[] calldata _concentrated) external; /// @notice sets the split of fees between LPs and voters function setFeeSplitCL(address[] calldata _pools, uint8[] calldata _feeProtocol) external; /// @notice sets the split of fees between LPs and voters for legacy pools function setFeeSplitLegacy(address[] calldata _pools, uint256[] calldata _feeSplits) external; /** * Voter governance */ /// @notice sets a new governor address in the voter.sol contract function setNewGovernorInVoter(address _newGovernor) external; /// @notice sets a new governor address in the voter.sol contract function setNewGovernorInOldVoter(address _newGovernor) external; /// @notice whitelists a token for governance, or removes if boolean is set to false function governanceWhitelist(address[] calldata _token, bool[] calldata _whitelisted) external; /// @notice kills active gauges, removing them from earning further emissions, and claims their fees prior function killGauge(address[] calldata _pairs) external; /// @notice revives inactive/killed gauges function reviveGauge(address[] calldata _pairs) external; /// @notice sets a new NFP Manager function setNfpManager(address _nfpManager) external; /// @notice syncs NFP Managers for gauges function syncNfpManager(address[] calldata gauges) external; /// @notice sets the ratio of xShadow/Shadow awarded globally to LPs function setEmissionsRatioInVoter(uint256 _pct) external; /// @notice sets the ratio of xShadow/Shadow awarded globally to LPs function setEmissionsRatioInOldVoter(uint256 _pct) external; /// @notice allows governance to retrieve emissions in the voter contract that will not be distributed due to the gauge being inactive /// @dev allows per-period retrieval for granularity function retrieveStuckEmissionsToGovernance(address _gauge, uint256 _period) external; /// @notice allows governance to retrieve emissions in the voter contract that will not be distributed due to the gauge being inactive /// @dev allows per-period retrieval for granularity function retrieveStuckEmissionsToGovernanceFromOldVoter(address _gauge, uint256 _period) external; /// @notice allows governance to designate a gauge as the "main" one, to prevent governance spam and confusion function setMainGaugeForClPair(address tokenA, address tokenB, address gauge) external; function resetVotesOnBehalfOf(address _user) external; function pokeVotesOnBehalfOf(address _user) external; function votesOnBehalfOf(address _user, address[] calldata _pools, uint256[] calldata _weights) external; /** * Reward List Functions */ /// @notice function for removing rewards for feeDistributors function removeFeeDistributorRewards(address[] calldata _pools, address[] calldata _rewards) external; /** * FeeCollector functions */ /// @notice Sets the treasury address to a new value. /// @param newTreasury The new address to set as the treasury. function setTreasuryInFeeCollector(address newTreasury) external; /// @notice Sets the value of treasury fees to a new amount. /// @param _treasuryFees The new amount of treasury fees to be set. function setTreasuryFeesInFeeCollector(uint256 _treasuryFees) external; /** * FeeRecipientFactory functions */ /// @notice set the fee % to be sent to the treasury /// @param _feeToTreasury the fee % to be sent to the treasury function setFeeToTreasuryInFeeRecipientFactory(uint256 _feeToTreasury) external; /// @notice set a new treasury address /// @param _treasury the new address function setTreasuryInFeeRecipientFactory(address _treasury) external; /** * CL Pool Factory functions */ /// @notice enables a tickSpacing with the given initialFee amount /// @dev unlike UniswapV3, we map via the tickSpacing rather than the fee tier /// @dev tickSpacings may never be removed once enabled /// @param tickSpacing The spacing between ticks to be enforced for all pools created /// @param initialFee The initial fee amount, denominated in hundredths of a bip (i.e. 1e-6) function enableTickSpacing(int24 tickSpacing, uint24 initialFee) external; /// @notice sets the feeProtocol (feeSplit) for new CL pools and stored in the factory function setGlobalClFeeProtocol(uint8 _feeProtocolGlobal) external; /// @notice sets the address of the voter in the v3 factory for gauge fee setting function setVoterAddressInFactoryV3(address _voter) external; /// @notice sets the address of the feeCollector in the v3 factory for fee routing function setFeeCollectorInFactoryV3(address _newFeeCollector) external; /** * Legacy Pool Factory functions */ /// @notice sets the treasury address in the legacy factory function setTreasuryInLegacyFactory(address _treasury) external; /// @notice enables or disables if there is a feeSplit when no gauge for legacy pairs function setFeeSplitWhenNoGauge(bool status) external; /// @notice set the default feeSplit in the legacy factory function setLegacyFeeSplitGlobal(uint256 _feeSplit) external; /// @notice set the fee recipient for legacy pairs function setLegacyFeeRecipient(address _pair, address _feeRecipient) external; /// @notice set the default swap fee for legacy pools function setLegacyFeeGlobal(uint256 _fee) external; /// @notice sets whether a pair can have skim() called or not for rebasing purposes function setSkimEnabledLegacy(address _pair, bool _status) external; /** * VoteModule Functions */ /// @notice sets addresses as exempt or removes their exemption function setCooldownExemption(address[] calldata _candidates, bool[] calldata _exempt) external; /// @notice function to change the cooldown in the voteModule function setNewVoteModuleCooldown(uint256 _newCooldown) external; /// @notice allows resetting of inactive votes to prevent dead votes function kickInactive(address[] calldata _nonparticipants) external; /** * Timelock gated functions */ /// @notice timelock gated payload execution in case tokens get stuck or other unexpected behaviors function execute(address _target, bytes calldata _payload) external; /// @notice timelock gated function to change the timelock function setNewTimelock(address _timelock) external; /// @notice function for initializing the voter contract with its dependencies function initializeVoter(IVoter.InitializationParams memory inputs) external; /// @notice backup distribute function backupDistribute() external; /// @notice backup distribute batch function backupDistributeBatch(uint256 startIndex, uint256 batchSize) external; /// @notice process required state changes before x33 updates function preX33UpdateHook(address user) external; /// @notice process required state changes after x33 updates function postX33UpdateHook() external; /// @notice allow distributing emissions via the accessHub function notifyEmissions(address[] calldata pools, uint256[] calldata emissions) external; /// @notice rescues token from Access Hub function rescue(address token) external; /// @notice rescues token from x33 function rescueFromX33(address _token, uint256 _amount) external; /// @notice rescues token from x33 adapater function rescueFromX33Adapter(address _token) external; } interface IAccessHub1 { /// @notice protocol timelock address function timelock() external view returns (address timelock); /// @notice protocol treasury address function treasury() external view returns (address treasury); /// @notice central voter contract function voter() external view returns (address); /// @notice weekly emissions minter function minter() external view returns (address); /// @notice launchpad plugin for augmenting feeshare function launcherPlugin() external view returns (address); /// @notice xShadow contract function xShadow() external view returns (address); /// @notice X33 contract function x33() external view returns (address); /// @notice adapter for X33 contract function x33Adapter() external view returns (address); /// @notice CL V3 factory function shadowV3PoolFactory() external view returns (address); /// @notice legacy pair factory function poolFactory() external view returns (address); /// @notice legacy fees holder contract function feeRecipientFactory() external view returns (address); /// @notice fee collector contract function feeCollector() external view returns (address); /// @notice voteModule contract function voteModule() external view returns (address); /// @notice NFPManager contract function nfpManager() external view returns (address); /// @notice concentrated (v3) gauge factory function clGaugeFactory() external view returns (address _clGaugeFactory); /// @notice legacy gauge factory address function gaugeFactory() external view returns (address _gaugeFactory); /// @notice the feeDistributor factory address function feeDistributorFactory() external view returns (address _feeDistributorFactory); /** * xShadow Functions */ /// @notice enables or disables the transfer whitelist in xShadow function transferWhitelistInXShadow(address[] calldata _who, bool[] calldata _whitelisted) external; /// @notice enables or disables the transfer TO whitelists in xShadow function transferToWhitelistInXShadow(address[] calldata _who, bool[] calldata _whitelisted) external; /// @notice enables or disables the governance in xShadow function toggleXShadowGovernance(bool enable) external; /// @notice allows redemption from the operator function operatorRedeemXShadow(uint256 _amount) external; /// @notice migrates the xShadow operator function migrateOperator(address _operator) external; /// @notice rescues any trapped tokens in xShadow function rescueTrappedTokens(address[] calldata _tokens, uint256[] calldata _amounts) external; /// @notice set dust threshold before a rebase can happen function setRebaseThreshold(uint256 _newThreshold) external; /** * LauncherPlugin specific functions */ /// @notice allows migrating the parameters from one pool to the other /// @param _oldPool the current address of the pair /// @param _newPool the new pool's address function migratePoolInLauncherPlugin(address _oldPool, address _newPool) external; /// @notice set launcher configurations for a pool /// @param _pool address of the pool /// @param _take the fee that goes to the designated recipient /// @param _recipient the address that receives the fees function setConfigsInLauncherPlugin(address _pool, uint256 _take, address _recipient) external; /// @notice enables the pool for LauncherConfigs /// @param _pool address of the pool function enablePoolInLauncherPlugin(address _pool) external; /// @notice disables the pool for LauncherConfigs /// @dev clears mappings /// @param _pool address of the pool function disablePoolInLauncherPlugin(address _pool) external; /// @notice sets a new operator address /// @param _newOperator new operator address function setOperatorInLauncherPlugin(address _newOperator) external; /// @notice gives authority to a new contract/address /// @param _newAuthority the suggested new authority function grantAuthorityInLauncherPlugin(address _newAuthority, string calldata _label) external; /// @notice governance ability to label each authority in the system with an arbitrary string function labelAuthorityInLauncherPlugin(address _authority, string calldata _label) external; /// @notice removes authority from a contract/address /// @param _oldAuthority the to-be-removed authority function revokeAuthorityInLauncherPlugin(address _oldAuthority) external; /** * X33 Functions */ /// @notice transfers the x33 operator address function transferOperatorInX33(address _newOperator) external; /// @notice whitelists aggregators in x33 function whitelistAggregatorInX33(address _newAggregator) external; /// @notice transfers the x33 Adapter operator address function transferOperatorInX33Adapter(address _newOperator) external; /** * Minter Functions */ /// @notice sets the inflation multiplier /// @param _multiplier the multiplier function setEmissionsMultiplierInMinter(uint256 _multiplier) external; /// @notice sets the inflation multiplier /// @param _multiplier the multiplier function setEmissionsMultiplierInOldMinter(uint256 _multiplier) external; /////////////////////////// /// Unordered Functions /// /////////////////////////// // These functions are not ordered according to contracts since AccessHub is full /// @notice poke votes for multiple users function pokeVotesOnBehalfOf(address[] calldata _users) external; /// @notice rebase using x33 tokens within the x33 contract function rebaseX33() external; /// @notice flash operations that needs a helper contract function flashExpand(address _flashExpansion, bytes memory data) external; /// @notice whitelist new gauge and fee distributor function whitelistGaugeAndFeeDistributorOnXShadow(address gauge, address feeDistributor) external; /// @notice create gauge on new voter function migrateGauges(address[] calldata gauges) external; /// @notice upgrades voter implementation function upgradeVoterImplementation(address _newVoterImplementation, bytes memory data) external; /// @notice upgrade minter implementation function upgradeMinterImplementation(address _newMinterImplementation, bytes memory data) external; /// @notice Sets implementation for all GaugeV3s function upgradeGaugeV3Implementation(address _newGaugeV3Implementation) external; /// @notice create gauge for pool, seeds the pool if needed function createGaugeForPool(address _pool) external; /// @notice returns the amount of tokens needs to seed a cl pool function amountForSeed(address pool) external view returns (uint256 amount0, uint256 amount1); /// @notice claims incentives on x33 function x33ClaimIncentives(address[] calldata _feeDistributors, address[][] calldata _tokens) external; /// @notice for when distribute is called too late and the team needs to update period data function updatePeriodDataInClGauge( address gauge, uint256 period, uint160 periodEndSecondsPerLiquidityCumulativeX128 ) external; } interface IAccessHubTemp { function registerExpansionPack2(address _newExpansionPack) external; function replaceExpansionPack2(address _oldExpansionPack, address _newExpansionPack) external; function removeExpansionPack2(address _expansionPack) external; function flashExpand2(address _flashExpansion, bytes memory data) external; /// @notice migrates fees to marble function migrateGaugeToMarble(address[] calldata gauges) external; } interface IAccessHub is IAccessControlEnumerable, IAccessHub0, IAccessHub1 { function DEFAULT_ADMIN_ROLE() external view returns (bytes32); function SWAP_FEE_SETTER() external view returns (bytes32); function PROTOCOL_OPERATOR() external view returns (bytes32); /// @notice central voter contract function oldVoter() external view returns (address); /// @notice weekly emissions minter function oldMinter() external view returns (address); /// @notice launchpad plugin for augmenting feeshare function oldLauncherPlugin() external view returns (address); /// @notice legacy fees holder contract function oldFeeRecipientFactory() external view returns (address); /// @notice fee collector contract function oldFeeCollector() external view returns (address); /// @notice concentrated (v3) gauge factory function oldClGaugeFactory() external view returns (address); /// @notice legacy gauge factory address function oldGaugeFactory() external view returns (address); /// @notice the feeDistributor factory address function oldFeeDistributorFactory() external view returns (address); /// @notice the voter proxy admin address function voterProxyAdmin() external view returns (address); /// @notice the minter proxy admin address function minterProxyAdmin() external view returns (address); }
// 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 xShadow in the caller's wallet function depositAll() external; /// @notice deposit a specified amount of xShadow function deposit(uint256 amount) external; /// @notice withdraw all xShadow function withdrawAll() external; /// @notice withdraw a specified amount of xShadow 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 xShadow contract to notify pending rebases /// @param amount the amount of Shadow to be notified from exit penalties function notifyRewardAmount(uint256 amount) external; /// @notice the address of the xShadow token (staking/voting token) /// @return _xShadow the address function xShadow() external view returns (address _xShadow); /// @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/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: 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 MainTickSpacingChanged(address indexed token0, address indexed token1, int24 indexed newMainTickSpacing); event Poke(address indexed user); event EmissionsRedirected(address indexed sourceGauge, address indexed destinationGauge); struct InitializationParams { address shadow; address legacyFactory; address gauges; address feeDistributorFactory; address minter; address msig; address xShadow; address clFactory; address clGaugeFactory; address nfpManager; address feeRecipientFactory; address voteModule; address launcherPlugin; address poolUpdater; } function initialize(InitializationParams memory inputs) external; /// @notice denominator basis function BASIS() external view returns (uint256); /// @notice ratio of xShadow emissions globally function xRatio() external view returns (uint256); /// @notice xShadow contract address function xShadow() 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 pool updater for CL function poolUpdater() 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 the address of the shadow launcher plugin to enable third party launchers /// @return _launcherPlugin the address of the plugin function launcherPlugin() external view returns (address _launcherPlugin); /// @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 _shadow emissions token contract address function shadow() external view returns (address _shadow); /// @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 claim arbitrary rewards from specific legacy gauges, and exit to shadow /// @param _gauges address of the gauges /// @param _tokens two dimensional array for the tokens to claim function claimLegacyRewardsAndExit(address[] calldata _gauges, address[][] calldata _tokens) external; /// @notice claim arbitrary rewards from specific cl gauges, and exit to shadow /// @param _gauges address of the gauges /// @param _tokens two dimensional array for the tokens to claim /// @param _nfpTokenIds two dimensional array for the nfp to claim function claimClGaugeRewardsAndExit( address[] memory _gauges, address[][] memory _tokens, uint256[][] memory _nfpTokenIds ) 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 xShadowRatio 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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.20; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Storage of the initializable contract. * * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions * when using with upgradeable contracts. * * @custom:storage-location erc7201:openzeppelin.storage.Initializable */ struct InitializableStorage { /** * @dev Indicates that the contract has been initialized. */ uint64 _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool _initializing; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00; /** * @dev The contract is already initialized. */ error InvalidInitialization(); /** * @dev The contract is not initializing. */ error NotInitializing(); /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint64 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in * production. * * Emits an {Initialized} event. */ modifier initializer() { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); // Cache values to avoid duplicated sloads bool isTopLevelCall = !$._initializing; uint64 initialized = $._initialized; // Allowed calls: // - initialSetup: the contract is not in the initializing state and no previous version was // initialized // - construction: the contract is initialized at version 1 (no reininitialization) and the // current contract is just being deployed bool initialSetup = initialized == 0 && isTopLevelCall; bool construction = initialized == 1 && address(this).code.length == 0; if (!initialSetup && !construction) { revert InvalidInitialization(); } $._initialized = 1; if (isTopLevelCall) { $._initializing = true; } _; if (isTopLevelCall) { $._initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint64 version) { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing || $._initialized >= version) { revert InvalidInitialization(); } $._initialized = version; $._initializing = true; _; $._initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { _checkInitializing(); _; } /** * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. */ function _checkInitializing() internal view virtual { if (!_isInitializing()) { revert NotInitializing(); } } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing) { revert InvalidInitialization(); } if ($._initialized != type(uint64).max) { $._initialized = type(uint64).max; emit Initialized(type(uint64).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint64) { return _getInitializableStorage()._initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _getInitializableStorage()._initializing; } /** * @dev Returns a pointer to the storage namespace. */ // solhint-disable-next-line var-name-mixedcase function _getInitializableStorage() private pure returns (InitializableStorage storage $) { assembly { $.slot := INITIALIZABLE_STORAGE } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at, * consider using {ReentrancyGuardTransient} instead. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } }
// SPDX-License-Identifier: MIT // 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: MIT // OpenZeppelin Contracts (last updated v5.1.0) (access/extensions/IAccessControlEnumerable.sol) pragma solidity ^0.8.20; import {IAccessControl} from "../IAccessControl.sol"; /** * @dev External interface of AccessControlEnumerable declared to support ERC-165 detection. */ interface IAccessControlEnumerable is IAccessControl { /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) external view returns (address); /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) external view returns (uint256); }
// 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) (access/IAccessControl.sol) pragma solidity ^0.8.20; /** * @dev External interface of AccessControl declared to support ERC-165 detection. */ interface IAccessControl { /** * @dev The `account` is missing a role. */ error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); /** * @dev The caller of a function is not the expected one. * * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}. */ error AccessControlBadConfirmation(); /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call. This account bears the admin role (for the granted role). * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `callerConfirmation`. */ function renounceRole(bytes32 role, address callerConfirmation) external; }
{ "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/=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/", "ds-test/=node_modules/ds-test/", "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": 333 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "cancun", "viaIR": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes","name":"returnData","type":"bytes"}],"name":"AggregatorFailed","type":"error"},{"inputs":[],"name":"CallFailed","type":"error"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"EnumerableMapNonexistentKey","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[{"internalType":"address","name":"aggregator","type":"address"}],"name":"InvalidAggregator","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[{"internalType":"uint256","name":"total","type":"uint256"}],"name":"InvalidTotalWeight","type":"error"},{"inputs":[{"internalType":"uint256","name":"weight","type":"uint256"}],"name":"InvalidWeight","type":"error"},{"inputs":[],"name":"NoBalance","type":"error"},{"inputs":[],"name":"NoMembers","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"NotMember","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"NotOperator","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"NotTimelock","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"NotTreasury","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"WARNING","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"aggregator","type":"address"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"AggregatorWhitelistUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"member","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Distribution","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"weight","type":"uint256"}],"name":"MemberUpdated","type":"event"},{"inputs":[{"internalType":"address[]","name":"_feeDistributors","type":"address[]"},{"internalType":"address[][]","name":"_tokens","type":"address[][]"}],"name":"claimIncentives","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimRebase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositXShadow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"emergencyExecute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllMembers","outputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"weights","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getMemberWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IXShadow","name":"_xShadow","type":"address"},{"internalType":"address","name":"_initialOperator","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverNative","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"_aggregator","type":"address"},{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"uint256","name":"_minAmountOut","type":"uint256"},{"internalType":"bytes","name":"_callData","type":"bytes"}],"internalType":"struct ShadowTreasury.AggregatorParams","name":"_params","type":"tuple"}],"name":"swapIncentiveViaAggregator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timelock","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryVotingPower","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_weight","type":"uint256"}],"name":"updateMember","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOperator","type":"address"}],"name":"updateOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"voteModule","outputs":[{"internalType":"contract IVoteModule","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voter","outputs":[{"internalType":"contract IVoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_aggregator","type":"address"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"whitelistAggregator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistedAggregators","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawXShadow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"xShadow","outputs":[{"internalType":"contract IXShadow","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6080604052348015600e575f5ffd5b5060015f556019601d565b60cd565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615606c5760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460ca5780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b612391806100da5f395ff3fe608060405234801561000f575f5ffd5b506004361061019a575f3560e01c80637c0f6b35116100e8578063a0321a5311610093578063b4cd143a1161006e578063b4cd143a14610351578063d33219b414610359578063d76499ff1461036c578063ee0b5af71461037f575f5ffd5b8063a0321a53146102f9578063ac7475ed1461030c578063b24c7d2f1461031f575f5ffd5b80638980f11f116100c35780638980f11f146102d557806396c82e57146102e8578063997072f7146102f1575f5ffd5b80637c0f6b351461029957806385caf28b146102af5780638624cfbc146102c2575f5ffd5b80635364df49116101485780635a54db86116101235780635a54db861461026b57806361d027b31461027357806363453ae114610286575f5ffd5b80635364df4914610232578063570ca735146102455780635898eaef14610258575f5ffd5b80634256f5e7116101785780634256f5e7146101e157806346c96aac1461020c578063485cc9551461021f575f5ffd5b80631994456c1461019e5780631fe834a2146101b9578063336137c8146101ce575b5f5ffd5b6101a6610392565b6040519081526020015b60405180910390f35b6101cc6101c7366004611dfe565b610583565b005b6101cc6101dc366004611e49565b610872565b6001546101f4906001600160a01b031681565b6040516001600160a01b0390911681526020016101b0565b6005546101f4906001600160a01b031681565b6101cc61022d366004611e73565b6108ad565b6101a6610240366004611eaa565b610e3d565b6006546101f4906001600160a01b031681565b6101cc610266366004611ed2565b610e86565b6101cc610ebd565b6003546101f4906001600160a01b031681565b6101cc610294366004611eaa565b610f6f565b6102a16111ae565b6040516101b0929190611efe565b6002546101f4906001600160a01b031681565b6101cc6102d0366004611f87565b6112b1565b6101cc6102e3366004611e49565b6113c9565b6101a6600b5481565b6101a661147c565b6101cc610307366004611f9e565b61148c565b6101cc61031a366004611eaa565b61156d565b61034161032d366004611eaa565b60076020525f908152604090205460ff1681565b60405190151581526020016101b0565b6101cc6115e3565b6004546101f4906001600160a01b031681565b6101cc61037a366004611f87565b61173f565b6101cc61038d36600461205f565b6118d8565b6002546040516246613160e11b81523060048201525f9182916001600160a01b0390911690628cc26290602401602060405180830381865afa1580156103da573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103fe91906120cb565b6001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610444573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061046891906120cb565b6002546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156104ae573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104d291906120cb565b6104dc91906120f6565b6104e691906120f6565b90505f60015f9054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610539573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061055d91906120cb565b90508061057283670de0b6b3a7640000612109565b61057c9190612120565b9250505090565b61058b611970565b6006546001600160a01b031633146105bd57604051633b63649d60e11b81523360048201526024015b60405180910390fd5b60075f6105cd6020840184611eaa565b6001600160a01b0316815260208101919091526040015f205460ff1661061f576105fa6020820182611eaa565b604051635c8bf34d60e01b81526001600160a01b0390911660048201526024016105b4565b6002546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015610665573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061068991906120cb565b905061069b6040830160208401611eaa565b6001600160a01b031663095ea7b36106b66020850185611eaa565b604080517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03909216600483015285013560248201526044016020604051808303815f875af115801561071a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061073e919061213f565b505f8061074e6020850185611eaa565b6001600160a01b0316610764608086018661215a565b60405161077292919061219d565b5f604051808303815f865af19150503d805f81146107ab576040519150601f19603f3d011682016040523d82523d5f602084013e6107b0565b606091505b5091509150816107d557806040516303740d9560e11b81526004016105b491906121ac565b6002546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa15801561081b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061083f91906120cb565b90508381101561086257604051637b7a260960e11b815260040160405180910390fd5b5050505061086f60015f55565b50565b6003546001600160a01b0316331461089f57604051632756308960e11b81523360048201526024016105b4565b6108a98282611998565b5050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff165f811580156108f25750825b90505f8267ffffffffffffffff16600114801561090e5750303b155b90508115801561091c575080155b1561093a5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561096457845460ff60401b1916600160401b1785555b6001600160a01b03871661098b5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0386166109b25760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03891690811790915560408051635cc490b560e11b815290515f929163b989216a9160048083019260209291908290030181865afa158015610a0b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a2f91906121e1565b9050806001600160a01b031663d33219b46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a6d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a9191906121e1565b600480546001600160a01b0319166001600160a01b03928316178155604080516361d027b360e01b81529051928416926361d027b3928281019260209291908290030181865afa158015610ae7573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b0b91906121e1565b60035f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001600160a01b03166385caf28b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b6c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b9091906121e1565b60025f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001600160a01b03166346c96aac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bf1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c1591906121e1565b600580546001600160a01b03199081166001600160a01b039384161790915560068054909116918916919091179055610c65735ebb8663b9d213026ad9776dba264c3ef1a40f37620186a0611998565b610c86739e9f5bf31b1b5387ea65f5b955fa0da0ed6f23ea620186a0611998565b610ca7735e363a8c41ebdcbcb32dc488ee610ee6580b1f8f620186a0611998565b610cc873796be2312e5c086640c67493ec01852300c4136b62015f90611998565b610ce973cafc58de1e6a071790efbb6b83b35397023e154462015f90611998565b610d0a736279bd15156592d1c744c3293145b9f9d0cb005162015f90611998565b610d2b73b3bfb32977cfd6200ab9537e3703e501d8381c9b620186a0611998565b610d4c73b9eb10ba936f35d5bdcca9b1cf477d6b152abfed620186a0611998565b610d6d73031f72deb03c509af42624ddcd1f63fce5ecb22062013880611998565b610d8e732860ce83720bab73b28e0179f64f2eaf810fd99562011170611998565b610dae73ec26de1b53436b959e534287888a297066cdd37d61ea60611998565b610dce73ce191069f6bea7f9bbbaf1fd73fd3cd4dbefb8c0614e20611998565b610ded73ac041df48df9791b0654f1dbbf2cc8450c5f2e9d6001611aca565b508315610e3457845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f610e49600883611b25565b8290610e74576040516305b5850b60e21b81526001600160a01b0390911660048201526024016105b4565b50610e80600883611b40565b92915050565b6004546001600160a01b03163314610eb35760405163167cd5f360e21b81523360048201526024016105b4565b6108a98282611aca565b610ec5611970565b6003546001600160a01b03163314610ef257604051632756308960e11b81523360048201526024016105b4565b6003546040515f916001600160a01b03169047908381818185875af1925050503d805f8114610f3c576040519150601f19603f3d011682016040523d82523d5f602084013e610f41565b606091505b5050905080610f63576040516312171d8360e31b815260040160405180910390fd5b50610f6d60015f55565b565b6006546001600160a01b03163314610f9c57604051633b63649d60e11b81523360048201526024016105b4565b610fa66008611b54565b5f03610fc557604051630292d7c360e51b815260040160405180910390fd5b6001600160a01b038116610fec5760405163d92e233d60e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa158015611030573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061105491906120cb565b9050805f0361107657604051636165515360e11b815260040160405180910390fd5b5f5b6110826008611b54565b8110156111a9575f80611096600884611b5e565b90925090505f620f42406110aa8387612109565b6110b49190612120565b9050801561119e5760405163a9059cbb60e01b81526001600160a01b038481166004830152602482018390525f919088169063a9059cbb906044016020604051808303815f875af115801561110b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061112f919061213f565b90508061114f576040516312171d8360e31b815260040160405180910390fd5b866001600160a01b0316846001600160a01b03167f022bd701e0d563742a0cf249c998c6c6a8db069e863592a0581053cdec2973ef8460405161119491815260200190565b60405180910390a3505b505050600101611078565b505050565b6060805f6111bc6008611b54565b90508067ffffffffffffffff8111156111d7576111d76121fc565b604051908082528060200260200182016040528015611200578160200160208202803683370190505b5092508067ffffffffffffffff81111561121c5761121c6121fc565b604051908082528060200260200182016040528015611245578160200160208202803683370190505b5091505f5b818110156112ab5761125d600882611b5e565b85838151811061126f5761126f612210565b6020026020010185848151811061128857611288612210565b60209081029190910101919091526001600160a01b03909116905260010161124a565b50509091565b6003546001600160a01b031633146112de57604051632756308960e11b81523360048201526024016105b4565b805f036112fe57604051631f2a200560e01b815260040160405180910390fd5b600254604051632e1a7d4d60e01b8152600481018390526001600160a01b0390911690632e1a7d4d906024015f604051808303815f87803b158015611341575f5ffd5b505af1158015611353573d5f5f3e3d5ffd5b505060015460405163a9059cbb60e01b8152336004820152602481018590526001600160a01b03909116925063a9059cbb91506044016020604051808303815f875af11580156113a5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108a9919061213f565b6113d1611970565b6003546001600160a01b031633146113fe57604051632756308960e11b81523360048201526024016105b4565b60035460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529083169063a9059cbb906044016020604051808303815f875af115801561144e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611472919061213f565b506108a960015f55565b5f6114876008611b54565b905090565b611494611970565b6004546001600160a01b031633146114c15760405163167cd5f360e21b81523360048201526024016105b4565b6001600160a01b0383166114e85760405163d92e233d60e01b815260040160405180910390fd5b5f836001600160a01b0316838360405161150392919061219d565b5f604051808303815f865af19150503d805f811461153c576040519150601f19603f3d011682016040523d82523d5f602084013e611541565b606091505b505090508061156357604051633204506f60e01b815260040160405180910390fd5b506111a960015f55565b6004546001600160a01b0316331461159a5760405163167cd5f360e21b81523360048201526024016105b4565b6001600160a01b0381166115c15760405163d92e233d60e01b815260040160405180910390fd5b600680546001600160a01b0319166001600160a01b0392909216919091179055565b6006546001600160a01b0316331461161057604051633b63649d60e11b81523360048201526024016105b4565b6002546040516246613160e11b81523060048201526001600160a01b0390911690628cc26290602401602060405180830381865afa158015611654573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061167891906120cb565b5060025f9054906101000a90046001600160a01b03166001600160a01b0316633d18b9126040518163ffffffff1660e01b81526004015f604051808303815f87803b1580156116c5575f5ffd5b505af11580156116d7573d5f5f3e3d5ffd5b5050505060025f9054906101000a90046001600160a01b03166001600160a01b031663de5f62686040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611727575f5ffd5b505af1158015611739573d5f5f3e3d5ffd5b50505050565b6003546001600160a01b0316331461176c57604051632756308960e11b81523360048201526024016105b4565b805f0361178c57604051631f2a200560e01b815260040160405180910390fd5b6001546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd906064016020604051808303815f875af11580156117e0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611804919061213f565b5060015460025460405163095ea7b360e01b81526001600160a01b0391821660048201526024810184905291169063095ea7b3906044016020604051808303815f875af1158015611857573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061187b919061213f565b5060025460405163b6b55f2560e01b8152600481018390526001600160a01b039091169063b6b55f25906024015f604051808303815f87803b1580156118bf575f5ffd5b505af11580156118d1573d5f5f3e3d5ffd5b5050505050565b6006546001600160a01b0316331461190557604051633b63649d60e11b81523360048201526024016105b4565b60055460405163183f9c7d60e11b81526001600160a01b039091169063307f38fa9061193d903090889088908890889060040161226c565b5f604051808303815f87803b158015611954575f5ffd5b505af1158015611966573d5f5f3e3d5ffd5b5050505050505050565b60025f540361199257604051633ee5aeb560e01b815260040160405180910390fd5b60025f55565b6001600160a01b0382166119bf5760405163e6c4247b60e01b815260040160405180910390fd5b620f42408111156119e657604051630d3f109960e31b8152600481018290526024016105b4565b6119f1600883611b25565b15611a1c575f611a02600884611b40565b905080600b5f828254611a159190612334565b9091555050505b80600b5f828254611a2d91906120f6565b9091555050600b54620f42401015611a5e57600b54604051635943317f60e01b81526004016105b491815260200190565b8015611a7657611a7060088383611b7b565b50611a83565b611a81600883611b98565b505b604080516001600160a01b0384168152602081018390527f721b01fe9b63fefb91c981e165c04d96058511dc990901f8d80c37dd2f6f695e91015b60405180910390a15050565b6001600160a01b0382165f81815260076020908152604091829020805460ff19168515159081179091558251938452908301527f51372928fc73bc5fef2c5bc8324eef22ddcbc66388d34c91e02f1e67b97159bb9101611abe565b5f611b39836001600160a01b038416611bac565b9392505050565b5f611b39836001600160a01b038416611bb7565b5f610e8082611bfd565b5f808080611b6c8686611c07565b909450925050505b9250929050565b5f611b90846001600160a01b03851684611c30565b949350505050565b5f611b39836001600160a01b038416611c4c565b5f611b398383611c68565b5f81815260028301602052604081205480158015611bdc5750611bda8484611bac565b155b15611b395760405163015ab34360e11b8152600481018490526024016105b4565b5f610e8082611c7f565b5f8080611c148585611c88565b5f81815260029690960160205260409095205494959350505050565b5f8281526002840160205260408120829055611b908484611c93565b5f8181526002830160205260408120819055611b398383611c9e565b5f8181526001830160205260408120541515611b39565b5f610e80825490565b5f611b398383611ca9565b5f611b398383611ccf565b5f611b398383611d1b565b5f825f018281548110611cbe57611cbe612210565b905f5260205f200154905092915050565b5f818152600183016020526040812054611d1457508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610e80565b505f610e80565b5f8181526001830160205260408120548015611df5575f611d3d600183612334565b85549091505f90611d5090600190612334565b9050808214611daf575f865f018281548110611d6e57611d6e612210565b905f5260205f200154905080875f018481548110611d8e57611d8e612210565b5f918252602080832090910192909255918252600188019052604090208390555b8554869080611dc057611dc0612347565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610e80565b5f915050610e80565b5f60208284031215611e0e575f5ffd5b813567ffffffffffffffff811115611e24575f5ffd5b820160a08185031215611b39575f5ffd5b6001600160a01b038116811461086f575f5ffd5b5f5f60408385031215611e5a575f5ffd5b8235611e6581611e35565b946020939093013593505050565b5f5f60408385031215611e84575f5ffd5b8235611e8f81611e35565b91506020830135611e9f81611e35565b809150509250929050565b5f60208284031215611eba575f5ffd5b8135611b3981611e35565b801515811461086f575f5ffd5b5f5f60408385031215611ee3575f5ffd5b8235611eee81611e35565b91506020830135611e9f81611ec5565b604080825283519082018190525f9060208501906060840190835b81811015611f405783516001600160a01b0316835260209384019390920191600101611f19565b5050838103602080860191909152855180835291810192508501905f5b81811015611f7b578251845260209384019390920191600101611f5d565b50919695505050505050565b5f60208284031215611f97575f5ffd5b5035919050565b5f5f5f60408486031215611fb0575f5ffd5b8335611fbb81611e35565b9250602084013567ffffffffffffffff811115611fd6575f5ffd5b8401601f81018613611fe6575f5ffd5b803567ffffffffffffffff811115611ffc575f5ffd5b86602082840101111561200d575f5ffd5b939660209190910195509293505050565b5f5f83601f84011261202e575f5ffd5b50813567ffffffffffffffff811115612045575f5ffd5b6020830191508360208260051b8501011115611b74575f5ffd5b5f5f5f5f60408587031215612072575f5ffd5b843567ffffffffffffffff811115612088575f5ffd5b6120948782880161201e565b909550935050602085013567ffffffffffffffff8111156120b3575f5ffd5b6120bf8782880161201e565b95989497509550505050565b5f602082840312156120db575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610e8057610e806120e2565b8082028115828204841417610e8057610e806120e2565b5f8261213a57634e487b7160e01b5f52601260045260245ffd5b500490565b5f6020828403121561214f575f5ffd5b8151611b3981611ec5565b5f5f8335601e1984360301811261216f575f5ffd5b83018035915067ffffffffffffffff821115612189575f5ffd5b602001915036819003821315611b74575f5ffd5b818382375f9101908152919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f602082840312156121f1575f5ffd5b8151611b3981611e35565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b8183526020830192505f815f5b8481101561226257813561224481611e35565b6001600160a01b031686526020958601959190910190600101612231565b5093949350505050565b6001600160a01b0386168152606060208201525f61228e606083018688612224565b8281036040840152838152602080820190600586901b830101865f36829003601e19015b8882101561232357858403601f1901855282358181126122d0575f5ffd5b8a0160208101903567ffffffffffffffff8111156122ec575f5ffd5b8060051b36038213156122fd575f5ffd5b612308868284612224565b955050506020830192506020850194506001820191506122b2565b50919b9a5050505050505050505050565b81810381811115610e8057610e806120e2565b634e487b7160e01b5f52603160045260245ffdfea26469706673582212200f403543619666562708a14f78e0af06f939598a498501dd6c023dc4c75bc64864736f6c634300081c0033
Deployed Bytecode
0x608060405234801561000f575f5ffd5b506004361061019a575f3560e01c80637c0f6b35116100e8578063a0321a5311610093578063b4cd143a1161006e578063b4cd143a14610351578063d33219b414610359578063d76499ff1461036c578063ee0b5af71461037f575f5ffd5b8063a0321a53146102f9578063ac7475ed1461030c578063b24c7d2f1461031f575f5ffd5b80638980f11f116100c35780638980f11f146102d557806396c82e57146102e8578063997072f7146102f1575f5ffd5b80637c0f6b351461029957806385caf28b146102af5780638624cfbc146102c2575f5ffd5b80635364df49116101485780635a54db86116101235780635a54db861461026b57806361d027b31461027357806363453ae114610286575f5ffd5b80635364df4914610232578063570ca735146102455780635898eaef14610258575f5ffd5b80634256f5e7116101785780634256f5e7146101e157806346c96aac1461020c578063485cc9551461021f575f5ffd5b80631994456c1461019e5780631fe834a2146101b9578063336137c8146101ce575b5f5ffd5b6101a6610392565b6040519081526020015b60405180910390f35b6101cc6101c7366004611dfe565b610583565b005b6101cc6101dc366004611e49565b610872565b6001546101f4906001600160a01b031681565b6040516001600160a01b0390911681526020016101b0565b6005546101f4906001600160a01b031681565b6101cc61022d366004611e73565b6108ad565b6101a6610240366004611eaa565b610e3d565b6006546101f4906001600160a01b031681565b6101cc610266366004611ed2565b610e86565b6101cc610ebd565b6003546101f4906001600160a01b031681565b6101cc610294366004611eaa565b610f6f565b6102a16111ae565b6040516101b0929190611efe565b6002546101f4906001600160a01b031681565b6101cc6102d0366004611f87565b6112b1565b6101cc6102e3366004611e49565b6113c9565b6101a6600b5481565b6101a661147c565b6101cc610307366004611f9e565b61148c565b6101cc61031a366004611eaa565b61156d565b61034161032d366004611eaa565b60076020525f908152604090205460ff1681565b60405190151581526020016101b0565b6101cc6115e3565b6004546101f4906001600160a01b031681565b6101cc61037a366004611f87565b61173f565b6101cc61038d36600461205f565b6118d8565b6002546040516246613160e11b81523060048201525f9182916001600160a01b0390911690628cc26290602401602060405180830381865afa1580156103da573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103fe91906120cb565b6001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610444573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061046891906120cb565b6002546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156104ae573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104d291906120cb565b6104dc91906120f6565b6104e691906120f6565b90505f60015f9054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610539573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061055d91906120cb565b90508061057283670de0b6b3a7640000612109565b61057c9190612120565b9250505090565b61058b611970565b6006546001600160a01b031633146105bd57604051633b63649d60e11b81523360048201526024015b60405180910390fd5b60075f6105cd6020840184611eaa565b6001600160a01b0316815260208101919091526040015f205460ff1661061f576105fa6020820182611eaa565b604051635c8bf34d60e01b81526001600160a01b0390911660048201526024016105b4565b6002546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015610665573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061068991906120cb565b905061069b6040830160208401611eaa565b6001600160a01b031663095ea7b36106b66020850185611eaa565b604080517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03909216600483015285013560248201526044016020604051808303815f875af115801561071a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061073e919061213f565b505f8061074e6020850185611eaa565b6001600160a01b0316610764608086018661215a565b60405161077292919061219d565b5f604051808303815f865af19150503d805f81146107ab576040519150601f19603f3d011682016040523d82523d5f602084013e6107b0565b606091505b5091509150816107d557806040516303740d9560e11b81526004016105b491906121ac565b6002546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa15801561081b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061083f91906120cb565b90508381101561086257604051637b7a260960e11b815260040160405180910390fd5b5050505061086f60015f55565b50565b6003546001600160a01b0316331461089f57604051632756308960e11b81523360048201526024016105b4565b6108a98282611998565b5050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff16159067ffffffffffffffff165f811580156108f25750825b90505f8267ffffffffffffffff16600114801561090e5750303b155b90508115801561091c575080155b1561093a5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561096457845460ff60401b1916600160401b1785555b6001600160a01b03871661098b5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0386166109b25760405163d92e233d60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03891690811790915560408051635cc490b560e11b815290515f929163b989216a9160048083019260209291908290030181865afa158015610a0b573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a2f91906121e1565b9050806001600160a01b031663d33219b46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a6d573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a9191906121e1565b600480546001600160a01b0319166001600160a01b03928316178155604080516361d027b360e01b81529051928416926361d027b3928281019260209291908290030181865afa158015610ae7573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b0b91906121e1565b60035f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001600160a01b03166385caf28b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b6c573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b9091906121e1565b60025f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001600160a01b03166346c96aac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bf1573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c1591906121e1565b600580546001600160a01b03199081166001600160a01b039384161790915560068054909116918916919091179055610c65735ebb8663b9d213026ad9776dba264c3ef1a40f37620186a0611998565b610c86739e9f5bf31b1b5387ea65f5b955fa0da0ed6f23ea620186a0611998565b610ca7735e363a8c41ebdcbcb32dc488ee610ee6580b1f8f620186a0611998565b610cc873796be2312e5c086640c67493ec01852300c4136b62015f90611998565b610ce973cafc58de1e6a071790efbb6b83b35397023e154462015f90611998565b610d0a736279bd15156592d1c744c3293145b9f9d0cb005162015f90611998565b610d2b73b3bfb32977cfd6200ab9537e3703e501d8381c9b620186a0611998565b610d4c73b9eb10ba936f35d5bdcca9b1cf477d6b152abfed620186a0611998565b610d6d73031f72deb03c509af42624ddcd1f63fce5ecb22062013880611998565b610d8e732860ce83720bab73b28e0179f64f2eaf810fd99562011170611998565b610dae73ec26de1b53436b959e534287888a297066cdd37d61ea60611998565b610dce73ce191069f6bea7f9bbbaf1fd73fd3cd4dbefb8c0614e20611998565b610ded73ac041df48df9791b0654f1dbbf2cc8450c5f2e9d6001611aca565b508315610e3457845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f610e49600883611b25565b8290610e74576040516305b5850b60e21b81526001600160a01b0390911660048201526024016105b4565b50610e80600883611b40565b92915050565b6004546001600160a01b03163314610eb35760405163167cd5f360e21b81523360048201526024016105b4565b6108a98282611aca565b610ec5611970565b6003546001600160a01b03163314610ef257604051632756308960e11b81523360048201526024016105b4565b6003546040515f916001600160a01b03169047908381818185875af1925050503d805f8114610f3c576040519150601f19603f3d011682016040523d82523d5f602084013e610f41565b606091505b5050905080610f63576040516312171d8360e31b815260040160405180910390fd5b50610f6d60015f55565b565b6006546001600160a01b03163314610f9c57604051633b63649d60e11b81523360048201526024016105b4565b610fa66008611b54565b5f03610fc557604051630292d7c360e51b815260040160405180910390fd5b6001600160a01b038116610fec5760405163d92e233d60e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa158015611030573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061105491906120cb565b9050805f0361107657604051636165515360e11b815260040160405180910390fd5b5f5b6110826008611b54565b8110156111a9575f80611096600884611b5e565b90925090505f620f42406110aa8387612109565b6110b49190612120565b9050801561119e5760405163a9059cbb60e01b81526001600160a01b038481166004830152602482018390525f919088169063a9059cbb906044016020604051808303815f875af115801561110b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061112f919061213f565b90508061114f576040516312171d8360e31b815260040160405180910390fd5b866001600160a01b0316846001600160a01b03167f022bd701e0d563742a0cf249c998c6c6a8db069e863592a0581053cdec2973ef8460405161119491815260200190565b60405180910390a3505b505050600101611078565b505050565b6060805f6111bc6008611b54565b90508067ffffffffffffffff8111156111d7576111d76121fc565b604051908082528060200260200182016040528015611200578160200160208202803683370190505b5092508067ffffffffffffffff81111561121c5761121c6121fc565b604051908082528060200260200182016040528015611245578160200160208202803683370190505b5091505f5b818110156112ab5761125d600882611b5e565b85838151811061126f5761126f612210565b6020026020010185848151811061128857611288612210565b60209081029190910101919091526001600160a01b03909116905260010161124a565b50509091565b6003546001600160a01b031633146112de57604051632756308960e11b81523360048201526024016105b4565b805f036112fe57604051631f2a200560e01b815260040160405180910390fd5b600254604051632e1a7d4d60e01b8152600481018390526001600160a01b0390911690632e1a7d4d906024015f604051808303815f87803b158015611341575f5ffd5b505af1158015611353573d5f5f3e3d5ffd5b505060015460405163a9059cbb60e01b8152336004820152602481018590526001600160a01b03909116925063a9059cbb91506044016020604051808303815f875af11580156113a5573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108a9919061213f565b6113d1611970565b6003546001600160a01b031633146113fe57604051632756308960e11b81523360048201526024016105b4565b60035460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529083169063a9059cbb906044016020604051808303815f875af115801561144e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611472919061213f565b506108a960015f55565b5f6114876008611b54565b905090565b611494611970565b6004546001600160a01b031633146114c15760405163167cd5f360e21b81523360048201526024016105b4565b6001600160a01b0383166114e85760405163d92e233d60e01b815260040160405180910390fd5b5f836001600160a01b0316838360405161150392919061219d565b5f604051808303815f865af19150503d805f811461153c576040519150601f19603f3d011682016040523d82523d5f602084013e611541565b606091505b505090508061156357604051633204506f60e01b815260040160405180910390fd5b506111a960015f55565b6004546001600160a01b0316331461159a5760405163167cd5f360e21b81523360048201526024016105b4565b6001600160a01b0381166115c15760405163d92e233d60e01b815260040160405180910390fd5b600680546001600160a01b0319166001600160a01b0392909216919091179055565b6006546001600160a01b0316331461161057604051633b63649d60e11b81523360048201526024016105b4565b6002546040516246613160e11b81523060048201526001600160a01b0390911690628cc26290602401602060405180830381865afa158015611654573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061167891906120cb565b5060025f9054906101000a90046001600160a01b03166001600160a01b0316633d18b9126040518163ffffffff1660e01b81526004015f604051808303815f87803b1580156116c5575f5ffd5b505af11580156116d7573d5f5f3e3d5ffd5b5050505060025f9054906101000a90046001600160a01b03166001600160a01b031663de5f62686040518163ffffffff1660e01b81526004015f604051808303815f87803b158015611727575f5ffd5b505af1158015611739573d5f5f3e3d5ffd5b50505050565b6003546001600160a01b0316331461176c57604051632756308960e11b81523360048201526024016105b4565b805f0361178c57604051631f2a200560e01b815260040160405180910390fd5b6001546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd906064016020604051808303815f875af11580156117e0573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611804919061213f565b5060015460025460405163095ea7b360e01b81526001600160a01b0391821660048201526024810184905291169063095ea7b3906044016020604051808303815f875af1158015611857573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061187b919061213f565b5060025460405163b6b55f2560e01b8152600481018390526001600160a01b039091169063b6b55f25906024015f604051808303815f87803b1580156118bf575f5ffd5b505af11580156118d1573d5f5f3e3d5ffd5b5050505050565b6006546001600160a01b0316331461190557604051633b63649d60e11b81523360048201526024016105b4565b60055460405163183f9c7d60e11b81526001600160a01b039091169063307f38fa9061193d903090889088908890889060040161226c565b5f604051808303815f87803b158015611954575f5ffd5b505af1158015611966573d5f5f3e3d5ffd5b5050505050505050565b60025f540361199257604051633ee5aeb560e01b815260040160405180910390fd5b60025f55565b6001600160a01b0382166119bf5760405163e6c4247b60e01b815260040160405180910390fd5b620f42408111156119e657604051630d3f109960e31b8152600481018290526024016105b4565b6119f1600883611b25565b15611a1c575f611a02600884611b40565b905080600b5f828254611a159190612334565b9091555050505b80600b5f828254611a2d91906120f6565b9091555050600b54620f42401015611a5e57600b54604051635943317f60e01b81526004016105b491815260200190565b8015611a7657611a7060088383611b7b565b50611a83565b611a81600883611b98565b505b604080516001600160a01b0384168152602081018390527f721b01fe9b63fefb91c981e165c04d96058511dc990901f8d80c37dd2f6f695e91015b60405180910390a15050565b6001600160a01b0382165f81815260076020908152604091829020805460ff19168515159081179091558251938452908301527f51372928fc73bc5fef2c5bc8324eef22ddcbc66388d34c91e02f1e67b97159bb9101611abe565b5f611b39836001600160a01b038416611bac565b9392505050565b5f611b39836001600160a01b038416611bb7565b5f610e8082611bfd565b5f808080611b6c8686611c07565b909450925050505b9250929050565b5f611b90846001600160a01b03851684611c30565b949350505050565b5f611b39836001600160a01b038416611c4c565b5f611b398383611c68565b5f81815260028301602052604081205480158015611bdc5750611bda8484611bac565b155b15611b395760405163015ab34360e11b8152600481018490526024016105b4565b5f610e8082611c7f565b5f8080611c148585611c88565b5f81815260029690960160205260409095205494959350505050565b5f8281526002840160205260408120829055611b908484611c93565b5f8181526002830160205260408120819055611b398383611c9e565b5f8181526001830160205260408120541515611b39565b5f610e80825490565b5f611b398383611ca9565b5f611b398383611ccf565b5f611b398383611d1b565b5f825f018281548110611cbe57611cbe612210565b905f5260205f200154905092915050565b5f818152600183016020526040812054611d1457508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610e80565b505f610e80565b5f8181526001830160205260408120548015611df5575f611d3d600183612334565b85549091505f90611d5090600190612334565b9050808214611daf575f865f018281548110611d6e57611d6e612210565b905f5260205f200154905080875f018481548110611d8e57611d8e612210565b5f918252602080832090910192909255918252600188019052604090208390555b8554869080611dc057611dc0612347565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610e80565b5f915050610e80565b5f60208284031215611e0e575f5ffd5b813567ffffffffffffffff811115611e24575f5ffd5b820160a08185031215611b39575f5ffd5b6001600160a01b038116811461086f575f5ffd5b5f5f60408385031215611e5a575f5ffd5b8235611e6581611e35565b946020939093013593505050565b5f5f60408385031215611e84575f5ffd5b8235611e8f81611e35565b91506020830135611e9f81611e35565b809150509250929050565b5f60208284031215611eba575f5ffd5b8135611b3981611e35565b801515811461086f575f5ffd5b5f5f60408385031215611ee3575f5ffd5b8235611eee81611e35565b91506020830135611e9f81611ec5565b604080825283519082018190525f9060208501906060840190835b81811015611f405783516001600160a01b0316835260209384019390920191600101611f19565b5050838103602080860191909152855180835291810192508501905f5b81811015611f7b578251845260209384019390920191600101611f5d565b50919695505050505050565b5f60208284031215611f97575f5ffd5b5035919050565b5f5f5f60408486031215611fb0575f5ffd5b8335611fbb81611e35565b9250602084013567ffffffffffffffff811115611fd6575f5ffd5b8401601f81018613611fe6575f5ffd5b803567ffffffffffffffff811115611ffc575f5ffd5b86602082840101111561200d575f5ffd5b939660209190910195509293505050565b5f5f83601f84011261202e575f5ffd5b50813567ffffffffffffffff811115612045575f5ffd5b6020830191508360208260051b8501011115611b74575f5ffd5b5f5f5f5f60408587031215612072575f5ffd5b843567ffffffffffffffff811115612088575f5ffd5b6120948782880161201e565b909550935050602085013567ffffffffffffffff8111156120b3575f5ffd5b6120bf8782880161201e565b95989497509550505050565b5f602082840312156120db575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610e8057610e806120e2565b8082028115828204841417610e8057610e806120e2565b5f8261213a57634e487b7160e01b5f52601260045260245ffd5b500490565b5f6020828403121561214f575f5ffd5b8151611b3981611ec5565b5f5f8335601e1984360301811261216f575f5ffd5b83018035915067ffffffffffffffff821115612189575f5ffd5b602001915036819003821315611b74575f5ffd5b818382375f9101908152919050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f602082840312156121f1575f5ffd5b8151611b3981611e35565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b8183526020830192505f815f5b8481101561226257813561224481611e35565b6001600160a01b031686526020958601959190910190600101612231565b5093949350505050565b6001600160a01b0386168152606060208201525f61228e606083018688612224565b8281036040840152838152602080820190600586901b830101865f36829003601e19015b8882101561232357858403601f1901855282358181126122d0575f5ffd5b8a0160208101903567ffffffffffffffff8111156122ec575f5ffd5b8060051b36038213156122fd575f5ffd5b612308868284612224565b955050506020830192506020850194506001820191506122b2565b50919b9a5050505050505050505050565b81810381811115610e8057610e806120e2565b634e487b7160e01b5f52603160045260245ffdfea26469706673582212200f403543619666562708a14f78e0af06f939598a498501dd6c023dc4c75bc64864736f6c634300081c0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
SONIC | 100.00% | $0.999827 | 39.1765 | $39.17 |
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.