Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00Multichain Info
N/A
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers.
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | ||||
|---|---|---|---|---|---|---|---|
| 15892342 | 1 min ago | 0 ETH | |||||
| 15892130 | 4 mins ago | 0 ETH | |||||
| 15892059 | 5 mins ago | 0 ETH | |||||
| 15891409 | 16 mins ago | 0 ETH | |||||
| 15891303 | 18 mins ago | 0 ETH | |||||
| 15891063 | 22 mins ago | 0 ETH | |||||
| 15890761 | 27 mins ago | 0 ETH | |||||
| 15889974 | 40 mins ago | 0 ETH | |||||
| 15889783 | 43 mins ago | 0 ETH | |||||
| 15889257 | 52 mins ago | 0 ETH | |||||
| 15889053 | 55 mins ago | 0 ETH | |||||
| 15888463 | 1 hr ago | 0 ETH | |||||
| 15888248 | 1 hr ago | 0 ETH | |||||
| 15887915 | 1 hr ago | 0 ETH | |||||
| 15887778 | 1 hr ago | 0 ETH | |||||
| 15886697 | 1 hr ago | 0 ETH | |||||
| 15886144 | 1 hr ago | 0 ETH | |||||
| 15885951 | 1 hr ago | 0 ETH | |||||
| 15885708 | 1 hr ago | 0 ETH | |||||
| 15885269 | 1 hr ago | 0 ETH | |||||
| 15884822 | 2 hrs ago | 0 ETH | |||||
| 15884542 | 2 hrs ago | 0 ETH | |||||
| 15884259 | 2 hrs ago | 0 ETH | |||||
| 15883476 | 2 hrs ago | 0 ETH | |||||
| 15883357 | 2 hrs ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
Distributor
Compiler Version
v0.8.25+commit.b61c2a91
Optimization Enabled:
Yes with 100 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.17;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import { UUPSHelper } from "./utils/UUPSHelper.sol";
import { IAccessControlManager } from "./interfaces/IAccessControlManager.sol";
import { Errors } from "./utils/Errors.sol";
struct MerkleTree {
// Root of a Merkle tree which leaves are `(address user, address token, uint amount)`
// representing an amount of tokens accumulated by `user`.
// The Merkle tree is assumed to have only increasing amounts: that is to say if a user can claim 1,
// then after the amount associated in the Merkle tree for this token should be x > 1
bytes32 merkleRoot;
// Ipfs hash of the tree data
bytes32 ipfsHash;
}
struct Claim {
uint208 amount;
uint48 timestamp;
bytes32 merkleRoot;
}
interface IClaimRecipient {
/// @notice Hook to call within contracts receiving token rewards on behalf of users
function onClaim(address user, address token, uint256 amount, bytes memory data) external returns (bytes32);
}
/// @title Distributor
/// @notice Allows to claim rewards distributed to them through Merkl
/// @author Angle Labs. Inc
contract Distributor is UUPSHelper {
using SafeERC20 for IERC20;
/// @notice Default epoch duration
uint32 internal constant _EPOCH_DURATION = 3600;
/// @notice Success message received when calling a `ClaimRecipient` contract
bytes32 public constant CALLBACK_SUCCESS = keccak256("IClaimRecipient.onClaim");
/*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
VARIABLES
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
/// @notice Tree of claimable tokens through this contract
MerkleTree public tree;
/// @notice Tree that was in place in the contract before the last `tree` update
MerkleTree public lastTree;
/// @notice Token to deposit to freeze the roots update
IERC20 public disputeToken;
/// @notice `AccessControlManager` contract handling access control
IAccessControlManager public accessControlManager;
/// @notice Address which created the last dispute
/// @dev Used to store if there is an ongoing dispute
address public disputer;
/// @notice When the current tree becomes valid
uint48 public endOfDisputePeriod;
/// @notice Time after which a change in a tree becomes effective, in EPOCH_DURATION
uint48 public disputePeriod;
/// @notice Amount to deposit to freeze the roots update
uint256 public disputeAmount;
/// @notice Mapping user -> token -> amount to track claimed amounts
mapping(address => mapping(address => Claim)) public claimed;
/// @notice Trusted EOAs to update the Merkle root
mapping(address => uint256) public canUpdateMerkleRoot;
/// @notice Deprecated mapping
mapping(address => uint256) public onlyOperatorCanClaim;
/// @notice User -> Operator -> authorisation to claim on behalf of the user
mapping(address => mapping(address => uint256)) public operators;
/// @notice Whether the contract has been made non upgradeable or not
uint128 public upgradeabilityDeactivated;
/// @notice Reentrancy status
uint96 private _status;
/// @notice Epoch duration for dispute periods (in seconds)
uint32 internal _epochDuration;
/// @notice user -> token -> recipient address for when user claims `token`
/// @dev If the mapping is empty, by default rewards will accrue on the user address
mapping(address => mapping(address => address)) public claimRecipient;
uint256[36] private __gap;
/*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
event Claimed(address indexed user, address indexed token, uint256 amount);
event ClaimRecipientUpdated(address indexed user, address indexed token, address indexed recipient);
event DisputeAmountUpdated(uint256 _disputeAmount);
event Disputed(string reason);
event DisputePeriodUpdated(uint48 _disputePeriod);
event DisputeResolved(bool valid);
event DisputeTokenUpdated(address indexed _disputeToken);
event EpochDurationUpdated(uint32 newEpochDuration);
event OperatorClaimingToggled(address indexed user, bool isEnabled);
event OperatorToggled(address indexed user, address indexed operator, bool isWhitelisted);
event Recovered(address indexed token, address indexed to, uint256 amount);
event Revoked(); // With this event an indexer could maintain a table (timestamp, merkleRootUpdate)
event TreeUpdated(bytes32 merkleRoot, bytes32 ipfsHash, uint48 endOfDisputePeriod);
event TrustedToggled(address indexed eoa, bool trust);
event UpgradeabilityRevoked();
/*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
MODIFIERS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
/// @notice Checks whether the `msg.sender` has the governor role
modifier onlyGovernor() {
if (!accessControlManager.isGovernor(msg.sender)) revert Errors.NotGovernor();
_;
}
/// @notice Checks whether the `msg.sender` is the `user` address or is a trusted address
modifier onlyTrustedOrUser(address user) {
if (
user != msg.sender &&
canUpdateMerkleRoot[msg.sender] != 1 &&
!accessControlManager.isGovernorOrGuardian(msg.sender)
) revert Errors.NotTrusted();
_;
}
/// @notice Checks whether the contract is upgradeable or whether the caller is allowed to upgrade the contract
modifier onlyUpgradeableInstance() {
if (upgradeabilityDeactivated == 1) revert Errors.NotUpgradeable();
else if (!accessControlManager.isGovernor(msg.sender)) revert Errors.NotGovernor();
_;
}
/// @notice Checks whether a call is reentrant or not
modifier nonReentrant() {
if (_status == 2) revert Errors.ReentrantCall();
// Any calls to nonReentrant after this point will fail
_status = 2;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = 1;
}
/*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
constructor() initializer {}
function initialize(IAccessControlManager _accessControlManager) external initializer {
if (address(_accessControlManager) == address(0)) revert Errors.ZeroAddress();
accessControlManager = _accessControlManager;
}
/// @inheritdoc UUPSHelper
function _authorizeUpgrade(address) internal view override onlyUpgradeableInstance {}
/*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
MAIN FUNCTIONS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
/// @notice Claims rewards for a given set of users
/// @dev Unless another address has been approved for claiming, only an address can claim for itself
/// @param users Addresses for which claiming is taking place
/// @param tokens ERC20 token claimed
/// @param amounts Amount of tokens that will be sent to the corresponding users
/// @param proofs Array of hashes bridging from a leaf `(hash of user | token | amount)` to the Merkle root
function claim(
address[] calldata users,
address[] calldata tokens,
uint256[] calldata amounts,
bytes32[][] calldata proofs
) external {
address[] memory recipients = new address[](users.length);
bytes[] memory datas = new bytes[](users.length);
_claim(users, tokens, amounts, proofs, recipients, datas);
}
/// @notice Same as the function above except that for each token claimed, the caller may set different
/// recipients for rewards and pass arbitrary data to the reward recipient on claim
/// @dev Only a `msg.sender` calling for itself can set a different recipient for the token rewards
/// within the context of a call to claim
/// @dev Non-zero recipient addresses given by the `msg.sender` can override any previously set reward address
function claimWithRecipient(
address[] calldata users,
address[] calldata tokens,
uint256[] calldata amounts,
bytes32[][] calldata proofs,
address[] calldata recipients,
bytes[] memory datas
) external {
_claim(users, tokens, amounts, proofs, recipients, datas);
}
/// @notice Returns the Merkle root that is currently live for the contract
function getMerkleRoot() public view returns (bytes32) {
if (block.timestamp >= endOfDisputePeriod && disputer == address(0)) return tree.merkleRoot;
else return lastTree.merkleRoot;
}
function getEpochDuration() public view returns (uint32 epochDuration) {
epochDuration = _epochDuration;
if (epochDuration == 0) epochDuration = _EPOCH_DURATION;
}
/*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
USER ADMIN FUNCTIONS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
/// @notice Toggles whitelisting for a given user and a given operator
/// @dev When an operator is whitelisted for a user, the operator can claim rewards on behalf of the user
function toggleOperator(address user, address operator) external onlyTrustedOrUser(user) {
uint256 oldValue = operators[user][operator];
operators[user][operator] = 1 - oldValue;
emit OperatorToggled(user, operator, oldValue == 0);
}
/// @notice Sets a recipient for a user claiming rewards for a token
/// @dev This is an optional functionality and if the `recipient` is set to the zero address, then
/// the user will still accrue all rewards to its address
/// @dev Users may still specify a different recipient when they claim token rewards with the
/// `claimWithRecipient` function
function setClaimRecipient(address recipient, address token) external {
claimRecipient[msg.sender][token] = recipient;
emit ClaimRecipientUpdated(msg.sender, recipient, token);
}
/// @notice Freezes the Merkle tree update until the dispute is resolved
/// @dev Requires a deposit of `disputeToken` that'll be slashed if the dispute is not accepted
/// @dev It is only possible to create a dispute within `disputePeriod` after each tree update
function disputeTree(string memory reason) external {
if (disputer != address(0)) revert Errors.UnresolvedDispute();
if (block.timestamp >= endOfDisputePeriod) revert Errors.InvalidDispute();
IERC20(disputeToken).safeTransferFrom(msg.sender, address(this), disputeAmount);
disputer = msg.sender;
emit Disputed(reason);
}
/*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
GOVERNANCE FUNCTIONS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
/// @notice Updates the Merkle tree
function updateTree(MerkleTree calldata _tree) external {
if (
disputer != address(0) ||
// A trusted address cannot update a tree right after a precedent tree update otherwise it can de facto
// validate a tree which has not passed the dispute period
((canUpdateMerkleRoot[msg.sender] != 1 || block.timestamp < endOfDisputePeriod) &&
!accessControlManager.isGovernor(msg.sender))
) revert Errors.NotTrusted();
MerkleTree memory _lastTree = tree;
tree = _tree;
lastTree = _lastTree;
uint48 _endOfPeriod = _endOfDisputePeriod(uint48(block.timestamp));
endOfDisputePeriod = _endOfPeriod;
emit TreeUpdated(_tree.merkleRoot, _tree.ipfsHash, _endOfPeriod);
}
/// @notice Adds or removes addresses which are trusted to update the Merkle root
function toggleTrusted(address trustAddress) external onlyGovernor {
uint256 trustedStatus = 1 - canUpdateMerkleRoot[trustAddress];
canUpdateMerkleRoot[trustAddress] = trustedStatus;
emit TrustedToggled(trustAddress, trustedStatus == 1);
}
/// @notice Prevents future contract upgrades
function revokeUpgradeability() external onlyGovernor {
upgradeabilityDeactivated = 1;
emit UpgradeabilityRevoked();
}
/// @notice Updates the epoch duration period
function setEpochDuration(uint32 epochDuration) external onlyGovernor {
_epochDuration = epochDuration;
emit EpochDurationUpdated(epochDuration);
}
/// @notice Resolve the ongoing dispute, if any
/// @param valid Whether the dispute was valid
function resolveDispute(bool valid) external onlyGovernor {
if (disputer == address(0)) revert Errors.NoDispute();
if (valid) {
IERC20(disputeToken).safeTransfer(disputer, disputeAmount);
// If a dispute is valid, the contract falls back to the last tree that was updated
_revokeTree();
} else {
IERC20(disputeToken).safeTransfer(msg.sender, disputeAmount);
endOfDisputePeriod = _endOfDisputePeriod(uint48(block.timestamp));
}
disputer = address(0);
emit DisputeResolved(valid);
}
/// @notice Allows the governor of this contract to fallback to the last version of the tree
/// immediately
function revokeTree() external onlyGovernor {
if (disputer != address(0)) revert Errors.UnresolvedDispute();
_revokeTree();
}
/// @notice Recovers any ERC20 token left on the contract
function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {
IERC20(tokenAddress).safeTransfer(to, amountToRecover);
emit Recovered(tokenAddress, to, amountToRecover);
}
/// @notice Sets the dispute period after which a tree update becomes effective
function setDisputePeriod(uint48 _disputePeriod) external onlyGovernor {
disputePeriod = uint48(_disputePeriod);
emit DisputePeriodUpdated(_disputePeriod);
}
/// @notice Sets the token used as a caution during disputes
function setDisputeToken(IERC20 _disputeToken) external onlyGovernor {
if (disputer != address(0)) revert Errors.UnresolvedDispute();
disputeToken = _disputeToken;
emit DisputeTokenUpdated(address(_disputeToken));
}
/// @notice Sets the amount of `disputeToken` used as a caution during disputes
function setDisputeAmount(uint256 _disputeAmount) external onlyGovernor {
if (disputer != address(0)) revert Errors.UnresolvedDispute();
disputeAmount = _disputeAmount;
emit DisputeAmountUpdated(_disputeAmount);
}
/*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
INTERNAL HELPERS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
/// @notice Internal version of `claimWithRecipient`
function _claim(
address[] calldata users,
address[] calldata tokens,
uint256[] calldata amounts,
bytes32[][] calldata proofs,
address[] memory recipients,
bytes[] memory datas
) internal nonReentrant {
uint256 usersLength = users.length;
if (
usersLength == 0 ||
usersLength != tokens.length ||
usersLength != amounts.length ||
usersLength != proofs.length ||
usersLength != recipients.length ||
usersLength != datas.length
) revert Errors.InvalidLengths();
for (uint256 i; i < usersLength; ) {
address user = users[i];
address token = tokens[i];
uint256 amount = amounts[i];
bytes memory data = datas[i];
// Only approved operator can claim for `user`
if (msg.sender != user && tx.origin != user && operators[user][msg.sender] == 0)
revert Errors.NotWhitelisted();
// Verifying proof
bytes32 leaf = keccak256(abi.encode(user, token, amount));
if (!_verifyProof(leaf, proofs[i])) revert Errors.InvalidProof();
// Closing reentrancy gate here
uint256 toSend = amount - claimed[user][token].amount;
claimed[user][token] = Claim(SafeCast.toUint208(amount), uint48(block.timestamp), getMerkleRoot());
emit Claimed(user, token, toSend);
address recipient = recipients[i];
// Only `msg.sender` can set a different recipient for itself within the context of a call to claim
// The recipient set in the context of the call to `claim` can override the default recipient set by the user
if (msg.sender != user || recipient == address(0)) {
address userSetRecipient = claimRecipient[user][token];
if (userSetRecipient == address(0)) recipient = user;
else recipient = userSetRecipient;
}
if (toSend != 0) {
IERC20(token).safeTransfer(recipient, toSend);
if (data.length != 0) {
try IClaimRecipient(recipient).onClaim(user, token, amount, data) returns (
bytes32 callbackSuccess
) {
if (callbackSuccess != CALLBACK_SUCCESS) revert Errors.InvalidReturnMessage();
} catch {}
}
}
unchecked {
++i;
}
}
}
/// @notice Fallback to the last version of the tree
function _revokeTree() internal {
MerkleTree memory _tree = lastTree;
endOfDisputePeriod = 0;
tree = _tree;
uint32 epochDuration = getEpochDuration();
emit Revoked();
emit TreeUpdated(
_tree.merkleRoot,
_tree.ipfsHash,
(uint48(block.timestamp) / epochDuration) * (epochDuration) // Last hour
);
}
/// @notice Returns the end of the dispute period
/// @dev treeUpdate is rounded up to next hour and then `disputePeriod` hours are added
function _endOfDisputePeriod(uint48 treeUpdate) internal view returns (uint48) {
uint32 epochDuration = getEpochDuration();
return ((treeUpdate - 1) / epochDuration + 1 + disputePeriod) * (epochDuration);
}
/// @notice Checks the validity of a proof
/// @param leaf Hashed leaf data, the starting point of the proof
/// @param proof Array of hashes forming a hash chain from leaf to root
/// @return true If proof is correct, else false
function _verifyProof(bytes32 leaf, bytes32[] memory proof) internal view returns (bool) {
bytes32 currentHash = leaf;
uint256 proofLength = proof.length;
for (uint256 i; i < proofLength; ) {
if (currentHash < proof[i]) {
currentHash = keccak256(abi.encode(currentHash, proof[i]));
} else {
currentHash = keccak256(abi.encode(proof[i], currentHash));
}
unchecked {
++i;
}
}
bytes32 root = getMerkleRoot();
if (root == bytes32(0)) revert Errors.InvalidUninitializedRoot();
return currentHash == root;
}
}// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.17;
/// @title IAccessControlManager
/// @author Angle Labs, Inc.
/// @notice Interface for the `AccessControlManager` contracts of Merkl contracts
interface IAccessControlManager {
/// @notice Checks whether an address is governor
/// @param admin Address to check
/// @return Whether the address has the `GOVERNOR_ROLE` or not
function isGovernor(address admin) external view returns (bool);
/// @notice Checks whether an address is a governor or a guardian of a module
/// @param admin Address to check
/// @return Whether the address has the `GUARDIAN_ROLE` or not
/// @dev Governance should make sure when adding a governor to also give this governor the guardian
/// role by calling the `addGovernor` function
function isGovernorOrGuardian(address admin) external view returns (bool);
}// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.17;
library Errors {
error CampaignDoesNotExist();
error CampaignAlreadyExists();
error CampaignDurationBelowHour();
error CampaignRewardTokenNotWhitelisted();
error CampaignRewardTooLow();
error CampaignShouldStartInFuture();
error InvalidDispute();
error InvalidLengths();
error InvalidOverride();
error InvalidParam();
error InvalidParams();
error InvalidProof();
error InvalidUninitializedRoot();
error InvalidReturnMessage();
error InvalidReward();
error InvalidSignature();
error KeyAlreadyUsed();
error NoDispute();
error NoOverrideForCampaign();
error NotAllowed();
error NotEnoughPayment();
error NotGovernor();
error NotGovernorOrGuardian();
error NotSigned();
error NotTrusted();
error NotUpgradeable();
error NotWhitelisted();
error UnresolvedDispute();
error ZeroAddress();
error DisputeFundsTransferFailed();
error EthNotAccepted();
error ReentrantCall();
error WithdrawalFailed();
error InvalidClaim();
error RefererNotSet();
}// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.17;
import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import { IAccessControlManager } from "../interfaces/IAccessControlManager.sol";
import { Errors } from "./Errors.sol";
/// @title UUPSHelper
/// @notice Helper contract for UUPSUpgradeable contracts where the upgradeability is controlled by a specific address
/// @author Angle Labs., Inc
/// @dev The 0 address check in the modifier allows the use of these modifiers during initialization
abstract contract UUPSHelper is UUPSUpgradeable {
modifier onlyGuardianUpgrader(IAccessControlManager _accessControlManager) {
if (address(_accessControlManager) != address(0) && !_accessControlManager.isGovernorOrGuardian(msg.sender))
revert Errors.NotGovernorOrGuardian();
_;
}
modifier onlyGovernorUpgrader(IAccessControlManager _accessControlManager) {
if (address(_accessControlManager) != address(0) && !_accessControlManager.isGovernor(msg.sender))
revert Errors.NotGovernor();
_;
}
constructor() initializer {}
/// @inheritdoc UUPSUpgradeable
function _authorizeUpgrade(address newImplementation) internal virtual override {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)
pragma solidity ^0.8.0;
/**
* @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.
*
* _Available since v4.8.3._
*/
interface IERC1967Upgradeable {
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Emitted when the beacon is changed.
*/
event BeaconUpgraded(address indexed beacon);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)
pragma solidity ^0.8.0;
/**
* @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
* proxy whose upgrades are fully controlled by the current implementation.
*/
interface IERC1822ProxiableUpgradeable {
/**
* @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
* address.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy.
*/
function proxiableUUID() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)
pragma solidity ^0.8.2;
import "../beacon/IBeaconUpgradeable.sol";
import "../../interfaces/IERC1967Upgradeable.sol";
import "../../interfaces/draft-IERC1822Upgradeable.sol";
import "../../utils/AddressUpgradeable.sol";
import "../../utils/StorageSlotUpgradeable.sol";
import "../utils/Initializable.sol";
/**
* @dev This abstract contract provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
*
* _Available since v4.1._
*/
abstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {
function __ERC1967Upgrade_init() internal onlyInitializing {
}
function __ERC1967Upgrade_init_unchained() internal onlyInitializing {
}
// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Returns the current implementation address.
*/
function _getImplementation() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract");
StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Perform implementation upgrade
*
* Emits an {Upgraded} event.
*/
function _upgradeTo(address newImplementation) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Perform implementation upgrade with additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {
_upgradeTo(newImplementation);
if (data.length > 0 || forceCall) {
AddressUpgradeable.functionDelegateCall(newImplementation, data);
}
}
/**
* @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {
// Upgrades from old implementations will perform a rollback test. This test requires the new
// implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing
// this special case will break upgrade paths from old UUPS implementation to new ones.
if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {
_setImplementation(newImplementation);
} else {
try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {
require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID");
} catch {
revert("ERC1967Upgrade: new implementation is not UUPS");
}
_upgradeToAndCall(newImplementation, data, forceCall);
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Returns the current admin.
*/
function _getAdmin() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
require(newAdmin != address(0), "ERC1967: new admin is the zero address");
StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*/
function _changeAdmin(address newAdmin) internal {
emit AdminChanged(_getAdmin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
*/
bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Returns the current beacon.
*/
function _getBeacon() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the EIP1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract");
require(
AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),
"ERC1967: beacon implementation is not a contract"
);
StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;
}
/**
* @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
* not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
*
* Emits a {BeaconUpgraded} event.
*/
function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {
_setBeacon(newBeacon);
emit BeaconUpgraded(newBeacon);
if (data.length > 0 || forceCall) {
AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);
}
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)
pragma solidity ^0.8.0;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeaconUpgradeable {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {BeaconProxy} will check that this address is a contract.
*/
function implementation() external view returns (address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
/**
* @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 Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 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 functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_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 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_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() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @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 {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized != type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)
pragma solidity ^0.8.0;
import "../../interfaces/draft-IERC1822Upgradeable.sol";
import "../ERC1967/ERC1967UpgradeUpgradeable.sol";
import "./Initializable.sol";
/**
* @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
* {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
*
* A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
* reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
* `UUPSUpgradeable` with a custom implementation of upgrades.
*
* The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
*
* _Available since v4.1._
*/
abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {
function __UUPSUpgradeable_init() internal onlyInitializing {
}
function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
}
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
address private immutable __self = address(this);
/**
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is
* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
* function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
* fail.
*/
modifier onlyProxy() {
require(address(this) != __self, "Function must be called through delegatecall");
require(_getImplementation() == __self, "Function must be called through active proxy");
_;
}
/**
* @dev Check that the execution is not being performed through a delegate call. This allows a function to be
* callable on the implementing contract but not through proxies.
*/
modifier notDelegated() {
require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall");
_;
}
/**
* @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
* implementation. It is used to validate the implementation's compatibility when performing an upgrade.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
*/
function proxiableUUID() external view virtual override notDelegated returns (bytes32) {
return _IMPLEMENTATION_SLOT;
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
*/
function upgradeTo(address newImplementation) public virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, new bytes(0), false);
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
* encoded in `data`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
*/
function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, data, true);
}
/**
* @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
* {upgradeTo} and {upgradeToAndCall}.
*
* Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
*
* ```solidity
* function _authorizeUpgrade(address) internal override onlyOwner {}
* ```
*/
function _authorizeUpgrade(address newImplementation) internal virtual;
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
pragma solidity ^0.8.0;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC1967 implementation slot:
* ```solidity
* contract ERC1967 {
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._
* _Available since v4.9 for `string`, `bytes`._
*/
library StorageSlotUpgradeable {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` with member `value` located at `slot`.
*/
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` representation of the string storage pointer `store`.
*/
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
/**
* @dev Returns an `BytesSlot` with member `value` located at `slot`.
*/
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
*/
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCast {
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toUint248(uint256 value) internal pure returns (uint248) {
require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toUint240(uint256 value) internal pure returns (uint240) {
require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toUint232(uint256 value) internal pure returns (uint232) {
require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.2._
*/
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toUint216(uint256 value) internal pure returns (uint216) {
require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toUint208(uint256 value) internal pure returns (uint208) {
require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toUint200(uint256 value) internal pure returns (uint200) {
require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toUint192(uint256 value) internal pure returns (uint192) {
require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toUint184(uint256 value) internal pure returns (uint184) {
require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toUint176(uint256 value) internal pure returns (uint176) {
require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toUint168(uint256 value) internal pure returns (uint168) {
require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toUint160(uint256 value) internal pure returns (uint160) {
require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toUint152(uint256 value) internal pure returns (uint152) {
require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toUint144(uint256 value) internal pure returns (uint144) {
require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toUint136(uint256 value) internal pure returns (uint136) {
require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v2.5._
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toUint120(uint256 value) internal pure returns (uint120) {
require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toUint112(uint256 value) internal pure returns (uint112) {
require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toUint104(uint256 value) internal pure returns (uint104) {
require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.2._
*/
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toUint88(uint256 value) internal pure returns (uint88) {
require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toUint80(uint256 value) internal pure returns (uint80) {
require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toUint72(uint256 value) internal pure returns (uint72) {
require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v2.5._
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toUint56(uint256 value) internal pure returns (uint56) {
require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toUint48(uint256 value) internal pure returns (uint48) {
require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toUint40(uint256 value) internal pure returns (uint40) {
require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v2.5._
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toUint24(uint256 value) internal pure returns (uint24) {
require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v2.5._
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v2.5._
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*
* _Available since v3.0._
*/
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.7._
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v3.1._
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.7._
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v3.1._
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v3.1._
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v3.1._
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v3.1._
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*
* _Available since v3.0._
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}{
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"appendCBOR": true,
"bytecodeHash": "ipfs",
"useLiteralContent": false
},
"optimizer": {
"enabled": true,
"runs": 100
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": [
"@openzeppelin/=node_modules/@openzeppelin/",
"forge-std/=node_modules/forge-std/src/",
"oz/=node_modules/@openzeppelin/contracts/",
"@utils/=node_modules/utils/src/",
"hardhat/=node_modules/hardhat/",
"lz/=node_modules/utils/lib/solidity-examples/contracts/",
"stringutils/=node_modules/utils/lib/solidity-stringutils/src/",
"utils/=node_modules/utils/"
],
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidDispute","type":"error"},{"inputs":[],"name":"InvalidLengths","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[],"name":"InvalidReturnMessage","type":"error"},{"inputs":[],"name":"InvalidUninitializedRoot","type":"error"},{"inputs":[],"name":"NoDispute","type":"error"},{"inputs":[],"name":"NotGovernor","type":"error"},{"inputs":[],"name":"NotTrusted","type":"error"},{"inputs":[],"name":"NotUpgradeable","type":"error"},{"inputs":[],"name":"NotWhitelisted","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"inputs":[],"name":"UnresolvedDispute","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"}],"name":"ClaimRecipientUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_disputeAmount","type":"uint256"}],"name":"DisputeAmountUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint48","name":"_disputePeriod","type":"uint48"}],"name":"DisputePeriodUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"valid","type":"bool"}],"name":"DisputeResolved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_disputeToken","type":"address"}],"name":"DisputeTokenUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"Disputed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"newEpochDuration","type":"uint32"}],"name":"EpochDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"isEnabled","type":"bool"}],"name":"OperatorClaimingToggled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"isWhitelisted","type":"bool"}],"name":"OperatorToggled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[],"name":"Revoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"ipfsHash","type":"bytes32"},{"indexed":false,"internalType":"uint48","name":"endOfDisputePeriod","type":"uint48"}],"name":"TreeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"eoa","type":"address"},{"indexed":false,"internalType":"bool","name":"trust","type":"bool"}],"name":"TrustedToggled","type":"event"},{"anonymous":false,"inputs":[],"name":"UpgradeabilityRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"CALLBACK_SUCCESS","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accessControlManager","outputs":[{"internalType":"contract IAccessControlManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"canUpdateMerkleRoot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes32[][]","name":"proofs","type":"bytes32[][]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"claimRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes32[][]","name":"proofs","type":"bytes32[][]"},{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"bytes[]","name":"datas","type":"bytes[]"}],"name":"claimWithRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"claimed","outputs":[{"internalType":"uint208","name":"amount","type":"uint208"},{"internalType":"uint48","name":"timestamp","type":"uint48"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disputeAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disputePeriod","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disputeToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"disputeTree","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disputer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endOfDisputePeriod","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEpochDuration","outputs":[{"internalType":"uint32","name":"epochDuration","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IAccessControlManager","name":"_accessControlManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastTree","outputs":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"ipfsHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"onlyOperatorCanClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"operators","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amountToRecover","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"valid","type":"bool"}],"name":"resolveDispute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revokeTree","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revokeUpgradeability","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"setClaimRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_disputeAmount","type":"uint256"}],"name":"setDisputeAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"_disputePeriod","type":"uint48"}],"name":"setDisputePeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_disputeToken","type":"address"}],"name":"setDisputeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"epochDuration","type":"uint32"}],"name":"setEpochDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"toggleOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"trustAddress","type":"address"}],"name":"toggleTrusted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tree","outputs":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"ipfsHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"ipfsHash","type":"bytes32"}],"internalType":"struct MerkleTree","name":"_tree","type":"tuple"}],"name":"updateTree","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"upgradeabilityDeactivated","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60a060405230608052348015610013575f80fd5b505f54610100900460ff161580801561003257505f54600160ff909116105b8061004b5750303b15801561004b57505f5460ff166001145b6100a05760405162461bcd60e51b815260206004820152602e60248201525f8051602061316083398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b5f805460ff1916600117905580156100c1575f805461ff0019166101001790555b80156100f3575f805461ff0019169055604051600181525f805160206131808339815191529060200160405180910390a15b505f54610100900460ff161580801561011257505f54600160ff909116105b8061012b5750303b15801561012b57505f5460ff166001145b61017b5760405162461bcd60e51b815260206004820152602e60248201525f8051602061316083398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610097565b5f805460ff19166001179055801561019c575f805461ff0019166101001790555b80156101ce575f805461ff0019169055604051600181525f805160206131808339815191529060200160405180910390a15b50608051612f5d6102035f395f8181610aac01528181610af501528181610d6801528181610da80152610e230152612f5d5ff3fe6080604052600436106101cb575f3560e01c8063623b9e9d116100f55780639fb67b581161008e5780639fb67b58146105f5578063b4a0bdf314610614578063bdac7ca314610633578063c4d66de814610652578063c748d26114610671578063cce80e7a14610690578063d9c98087146106bf578063e57480e5146106de578063fd54b22814610709575f80fd5b8063623b9e9d146104bd57806368508c98146104dc5780636ac56103146104fb57806371ee95c01461051a5780637be1c8f8146105395780637ee84349146105705780638237e5381461058f57806389e1e82a146105c257806395788835146105e1575f80fd5b80633a5345ab116101675780633a5345ab146103795780634641fdef1461038d57806349590657146103ac5780634d272d95146103c05780634f1ef2861461040c57806352d1902d1461041f5780635bf31d4d146104335780635cec892a1461046f5780635d3ea8f114610494575f80fd5b806309454ba3146101cf5780630c9cbf0e146101f75780630d10fca31461027b5780631171bda91461029c57806314769142146102bb57806314c8d37d146102e65780632637588e146103055780632a25dd411461033b5780633659cfe61461035a575b5f80fd5b3480156101da575f80fd5b506101e4606c5481565b6040519081526020015b60405180910390f35b348015610202575f80fd5b5061024f610211366004612722565b606d60209081525f9283526040808420909152908252902080546001909101546001600160d01b03821691600160d01b900465ffffffffffff169083565b604080516001600160d01b03909416845265ffffffffffff9092166020840152908201526060016101ee565b348015610286575f80fd5b5061029a610295366004612759565b610723565b005b3480156102a7575f80fd5b5061029a6102b6366004612770565b610815565b3480156102c6575f80fd5b506101e46102d53660046127ae565b606f6020525f908152604090205481565b3480156102f1575f80fd5b5061029a6103003660046127c9565b610907565b348015610310575f80fd5b506101e461031f366004612722565b607060209081525f928352604080842090915290825290205481565b348015610346575f80fd5b5061029a610355366004612884565b6109e6565b348015610365575f80fd5b5061029a6103743660046127ae565b610aa2565b348015610384575f80fd5b5061029a610b72565b348015610398575f80fd5b5061029a6103a73660046128c8565b610c3b565b3480156103b7575f80fd5b506101e4610d1c565b3480156103cb575f80fd5b506103ff6103da366004612722565b607260209081525f92835260408084209091529082529020546001600160a01b031681565b6040516101ee91906128ed565b61029a61041a36600461291f565b610d5e565b34801561042a575f80fd5b506101e4610e17565b34801561043e575f80fd5b50606b5461045890600160d01b900465ffffffffffff1681565b60405165ffffffffffff90911681526020016101ee565b34801561047a575f80fd5b50606b5461045890600160a01b900465ffffffffffff1681565b34801561049f575f80fd5b506104a8610ec3565b60405163ffffffff90911681526020016101ee565b3480156104c8575f80fd5b5061029a6104d73660046127ae565b610ee2565b3480156104e7575f80fd5b5061029a6104f6366004612722565b610fe1565b348015610506575f80fd5b50606b546103ff906001600160a01b031681565b348015610525575f80fd5b5061029a6105343660046129b2565b611048565b348015610544575f80fd5b50607154610558906001600160801b031681565b6040516001600160801b0390911681526020016101ee565b34801561057b575f80fd5b5061029a61058a3660046127ae565b6110fa565b34801561059a575f80fd5b506101e47f41263d2f619e70e9cb211899844b4cf7322f9939361a152780541ef1d2031cb681565b3480156105cd575f80fd5b5061029a6105dc366004612a79565b611203565b3480156105ec575f80fd5b5061029a611379565b348015610600575f80fd5b5061029a61060f366004612b2d565b611439565b34801561061f575f80fd5b50606a546103ff906001600160a01b031681565b34801561063e575f80fd5b5061029a61064d366004612722565b61148b565b34801561065d575f80fd5b5061029a61066c3660046127ae565b6115e0565b34801561067c575f80fd5b506069546103ff906001600160a01b031681565b34801561069b575f80fd5b506067546068546106aa919082565b604080519283526020830191909152016101ee565b3480156106ca575f80fd5b5061029a6106d9366004612c35565b611726565b3480156106e9575f80fd5b506101e46106f83660046127ae565b606e6020525f908152604090205481565b348015610714575f80fd5b506065546066546106aa919082565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b8906107539033906004016128ed565b602060405180830381865afa15801561076e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107929190612c4b565b6107af57604051633b8d9d7560e21b815260040160405180910390fd5b606b546001600160a01b0316156107d957604051630160c95d60e21b815260040160405180910390fd5b606c8190556040518181527f39bb629f3d59f5eddf978050e1f5fabeca2b5d02dfc9c25e84f32e7da1069db4906020015b60405180910390a150565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b8906108459033906004016128ed565b602060405180830381865afa158015610860573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108849190612c4b565b6108a157604051633b8d9d7560e21b815260040160405180910390fd5b6108b56001600160a01b03841683836118ac565b816001600160a01b0316836001600160a01b03167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b648836040516108fa91815260200190565b60405180910390a3505050565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b8906109379033906004016128ed565b602060405180830381865afa158015610952573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109769190612c4b565b61099357604051633b8d9d7560e21b815260040160405180910390fd5b607180546001600160e01b0316600160e01b63ffffffff8416908102919091179091556040519081527f83b318614a148a5806087ebf98a15a44e2a3fd3f57b829f39f4396c53c6b8cc39060200161080a565b606b546001600160a01b031615610a1057604051630160c95d60e21b815260040160405180910390fd5b606b54600160a01b900465ffffffffffff164210610a4157604051631a8f039560e01b815260040160405180910390fd5b606c54606954610a60916001600160a01b039091169033903090611914565b606b80546001600160a01b031916331790556040517f5eca00b8ed745eee61451333090bfa56aa1f2a9e696a2aebe5f1f5b6cef6f2ff9061080a908390612c94565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610af35760405162461bcd60e51b8152600401610aea90612ca6565b60405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610b2561193b565b6001600160a01b031614610b4b5760405162461bcd60e51b8152600401610aea90612cf2565b610b5481611956565b604080515f80825260208201909252610b6f91839190611a0e565b50565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b890610ba29033906004016128ed565b602060405180830381865afa158015610bbd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610be19190612c4b565b610bfe57604051633b8d9d7560e21b815260040160405180910390fd5b607180546001600160801b03191660011790556040517fba5b67b940ab06d91fe570b3522545e329c2d970f23e0b6453e76431724402c9905f90a1565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b890610c6b9033906004016128ed565b602060405180830381865afa158015610c86573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610caa9190612c4b565b610cc757604051633b8d9d7560e21b815260040160405180910390fd5b606b80546001600160d01b0316600160d01b65ffffffffffff8416908102919091179091556040519081527ffdf22e84af74bd4ab6b9646f6370a02bc886ed6ac25882db14e4ebf4b8e3bc7e9060200161080a565b606b545f90600160a01b900465ffffffffffff164210801590610d485750606b546001600160a01b0316155b15610d54575060655490565b5060675490565b90565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610da65760405162461bcd60e51b8152600401610aea90612ca6565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610dd861193b565b6001600160a01b031614610dfe5760405162461bcd60e51b8152600401610aea90612cf2565b610e0782611956565b610e1382826001611a0e565b5050565b5f306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610eb15760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c6044820152771b1959081d1a1c9bdd59da0819195b1959d85d1958d85b1b60421b6064820152608401610aea565b505f80516020612ee183398151915290565b607154600160e01b900463ffffffff165f819003610d5b5750610e1090565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b890610f129033906004016128ed565b602060405180830381865afa158015610f2d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f519190612c4b565b610f6e57604051633b8d9d7560e21b815260040160405180910390fd5b606b546001600160a01b031615610f9857604051630160c95d60e21b815260040160405180910390fd5b606980546001600160a01b0319166001600160a01b0383169081179091556040517f1db8d6629941dcb63d5e0c927b89c174c714e139a4b9107a49de839d755f5d74905f90a250565b335f8181526072602090815260408083206001600160a01b038681168086529190935281842080546001600160a01b03191693881693841790559051909391927f65e683f3800bc24dc7a30e42fb2e833290a4725be8b3658038a3f5d502f3d29f91a45050565b5f876001600160401b03811115611061576110616127ec565b60405190808252806020026020018201604052801561108a578160200160208202803683370190505b5090505f886001600160401b038111156110a6576110a66127ec565b6040519080825280602002602001820160405280156110d957816020015b60608152602001906001900390816110c45790505b5090506110ee8a8a8a8a8a8a8a8a8a8a611b78565b50505050505050505050565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b89061112a9033906004016128ed565b602060405180830381865afa158015611145573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111699190612c4b565b61118657604051633b8d9d7560e21b815260040160405180910390fd5b6001600160a01b0381165f908152606e60205260408120546111a9906001612d52565b6001600160a01b0383165f818152606e6020908152604091829020849055905160018414815292935090917f7628ea5f6112a16b36a8239aa208395a8e8f221688cfb3a5461faffb9700abcd910160405180910390a25050565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b8906112339033906004016128ed565b602060405180830381865afa15801561124e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112729190612c4b565b61128f57604051633b8d9d7560e21b815260040160405180910390fd5b606b546001600160a01b03166112b85760405163126ea8e960e31b815260040160405180910390fd5b80156112ec57606b54606c546069546112df926001600160a01b03918216929116906118ac565b6112e7612069565b611337565b606c54606954611309916001600160a01b039091169033906118ac565b6113124261213a565b606b60146101000a81548165ffffffffffff021916908365ffffffffffff1602179055505b606b80546001600160a01b031916905560405181151581527f8015c5005d9ad5d85ca80d3f894f08e0159277704c54166e5cff108800fa80cd9060200161080a565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b8906113a99033906004016128ed565b602060405180830381865afa1580156113c4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113e89190612c4b565b61140557604051633b8d9d7560e21b815260040160405180910390fd5b606b546001600160a01b03161561142f57604051630160c95d60e21b815260040160405180910390fd5b611437612069565b565b61147e8b8b8b8b8b8b8b8b8b8b808060200260200160405190810160405280939291908181526020018383602002808284375f920191909152508d9250611b78915050565b5050505050505050505050565b816001600160a01b03811633148015906114b45750335f908152606e6020526040902054600114155b801561152c5750606a5460405163521d4de960e01b81526001600160a01b039091169063521d4de9906114eb9033906004016128ed565b602060405180830381865afa158015611506573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061152a9190612c4b565b155b1561154a57604051636115324760e11b815260040160405180910390fd5b6001600160a01b038084165f9081526070602090815260408083209386168352929052205461157a816001612d52565b6001600160a01b038581165f81815260706020908152604080832094891680845294825291829020949094555184158152919290917f42343f44c66ea1eaffa334760d3da2cb731d2a0b3b3e30423df997faa36cc95c910160405180910390a350505050565b5f54610100900460ff16158080156115fe57505f54600160ff909116105b806116175750303b15801561161757505f5460ff166001145b61167a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610aea565b5f805460ff19166001179055801561169b575f805461ff0019166101001790555b6001600160a01b0382166116c25760405163d92e233d60e01b815260040160405180910390fd5b606a80546001600160a01b0319166001600160a01b0384161790558015610e13575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15050565b606b546001600160a01b03161515806117e05750335f908152606e602052604090205460011415806117685750606b54600160a01b900465ffffffffffff1642105b80156117e05750606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b89061179f9033906004016128ed565b602060405180830381865afa1580156117ba573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117de9190612c4b565b155b156117fe57604051636115324760e11b815260040160405180910390fd5b604080518082019091526065805480835260668054602080860182905286359094559285013590556067556068555f6118364261213a565b606b805465ffffffffffff60a01b1916600160a01b65ffffffffffff841690810291909117909155604080518635815260208088013590820152908101919091529091507f23aa2e4f757a7bd974085d3e11439a843b137b30905e3ffd51b2097c34aef62e9060600160405180910390a1505050565b6040516001600160a01b03831660248201526044810182905261190f90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261219d565b505050565b611935846323b872dd60e01b8585856040516024016118d893929190612d65565b50505050565b5f80516020612ee1833981519152546001600160a01b031690565b6071546001600160801b03166001036119825760405163229b36d360e01b815260040160405180910390fd5b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b8906119b29033906004016128ed565b602060405180830381865afa1580156119cd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119f19190612c4b565b610b6f57604051633b8d9d7560e21b815260040160405180910390fd5b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611a415761190f83612270565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611a9b575060408051601f3d908101601f19168201909252611a9891810190612d89565b60015b611afe5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610aea565b5f80516020612ee18339815191528114611b6c5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610aea565b5061190f83838361230b565b607154600160801b90046bffffffffffffffffffffffff16600203611bb0576040516306fda65d60e31b815260040160405180910390fd5b60718054600160801b600160e01b031916600160811b17905588801580611bd75750808814155b80611be25750808614155b80611bed5750808414155b80611bf9575082518114155b80611c05575081518114155b15611c2357604051631df89e8b60e01b815260040160405180910390fd5b5f5b81811015612042575f8c8c83818110611c4057611c40612da0565b9050602002016020810190611c5591906127ae565b90505f8b8b84818110611c6a57611c6a612da0565b9050602002016020810190611c7f91906127ae565b90505f8a8a85818110611c9457611c94612da0565b9050602002013590505f868581518110611cb057611cb0612da0565b60200260200101519050836001600160a01b0316336001600160a01b031614158015611ce55750326001600160a01b03851614155b8015611d1157506001600160a01b0384165f908152607060209081526040808320338452909152902054155b15611d2f57604051630b094f2760e31b815260040160405180910390fd5b5f848484604051602001611d4593929190612d65565b604051602081830303815290604052805190602001209050611dbb818c8c89818110611d7357611d73612da0565b9050602002810190611d859190612db4565b808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525061232f92505050565b611dd8576040516309bde33960e01b815260040160405180910390fd5b6001600160a01b038086165f908152606d60209081526040808320938816835292905290812054611e12906001600160d01b031685612d52565b90506040518060600160405280611e2886612440565b6001600160d01b031681526020014265ffffffffffff168152602001611e4c610d1c565b90526001600160a01b038781165f818152606d60209081526040808320948b168084529482529182902085518683015165ffffffffffff16600160d01b026001600160d01b039091161781559482015160019095019490945551848152919290917ff7a40077ff7a04c7e61f6f26fb13774259ddf1b6bce9ecf26a8276cdd3992683910160405180910390a35f8a8881518110611eeb57611eeb612da0565b60200260200101519050866001600160a01b0316336001600160a01b0316141580611f1d57506001600160a01b038116155b15611f5c576001600160a01b038088165f9081526072602090815260408083208a851684529091529020541680611f5657879150611f5a565b8091505b505b811561203057611f766001600160a01b03871682846118ac565b83511561203057604051635f20da2d60e01b81526001600160a01b03821690635f20da2d90611faf908a908a908a908a90600401612df9565b6020604051808303815f875af1925050508015611fe9575060408051601f3d908101601f19168201909252611fe691810190612d89565b60015b15612030577f41263d2f619e70e9cb211899844b4cf7322f9939361a152780541ef1d2031cb6811461202e5760405163ee418e3760e01b815260040160405180910390fd5b505b87600101975050505050505050611c25565b505060718054600160801b600160e01b031916600160801b17905550505050505050505050565b6040805180820190915260675480825260685460208301819052606b805465ffffffffffff60a01b191690556065919091556066555f6120a7610ec3565b6040519091507f44825a4b2df8acb19ce4e1afba9aa850c8b65cdb7942e2078f27d0b0960efee6905f90a1815160208301517f23aa2e4f757a7bd974085d3e11439a843b137b30905e3ffd51b2097c34aef62e919063ffffffff841661210d8142612e2b565b6121179190612e5b565b60408051938452602084019290925265ffffffffffff169082015260600161171a565b5f80612144610ec3565b606b5490915063ffffffff821690600160d01b900465ffffffffffff168161216d600187612e85565b6121779190612e2b565b612182906001612eab565b61218c9190612eab565b6121969190612e5b565b9392505050565b5f6121f1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166124ac9092919063ffffffff16565b905080515f14806122115750808060200190518101906122119190612c4b565b61190f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610aea565b6001600160a01b0381163b6122dd5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610aea565b5f80516020612ee183398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b612314836124c2565b5f825111806123205750805b1561190f576119358383612501565b80515f908390825b818110156124085784818151811061235157612351612da0565b60200260200101518310156123b2578285828151811061237357612373612da0565b6020026020010151604051602001612395929190918252602082015260400190565b604051602081830303815290604052805190602001209250612400565b8481815181106123c4576123c4612da0565b6020026020010151836040516020016123e7929190918252602082015260400190565b6040516020818303038152906040528051906020012092505b600101612337565b505f612412610d1c565b905080612432576040516301295acb60e31b815260040160405180910390fd5b919091149150505b92915050565b5f6001600160d01b038211156124a85760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663038206269747360c81b6064820152608401610aea565b5090565b60606124ba84845f85612526565b949350505050565b6124cb81612270565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b60606121968383604051806060016040528060278152602001612f01602791396125fd565b6060824710156125875760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610aea565b5f80866001600160a01b031685876040516125a29190612eca565b5f6040518083038185875af1925050503d805f81146125dc576040519150601f19603f3d011682016040523d82523d5f602084013e6125e1565b606091505b50915091506125f287838387612671565b979650505050505050565b60605f80856001600160a01b0316856040516126199190612eca565b5f60405180830381855af49150503d805f8114612651576040519150601f19603f3d011682016040523d82523d5f602084013e612656565b606091505b509150915061266786838387612671565b9695505050505050565b606083156126df5782515f036126d8576001600160a01b0385163b6126d85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aea565b50816124ba565b6124ba83838151156126f45781518083602001fd5b8060405162461bcd60e51b8152600401610aea9190612c94565b6001600160a01b0381168114610b6f575f80fd5b5f8060408385031215612733575f80fd5b823561273e8161270e565b9150602083013561274e8161270e565b809150509250929050565b5f60208284031215612769575f80fd5b5035919050565b5f805f60608486031215612782575f80fd5b833561278d8161270e565b9250602084013561279d8161270e565b929592945050506040919091013590565b5f602082840312156127be575f80fd5b81356121968161270e565b5f602082840312156127d9575f80fd5b813563ffffffff81168114612196575f80fd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715612828576128286127ec565b604052919050565b5f6001600160401b03831115612848576128486127ec565b61285b601f8401601f1916602001612800565b905082815283838301111561286e575f80fd5b828260208301375f602084830101529392505050565b5f60208284031215612894575f80fd5b81356001600160401b038111156128a9575f80fd5b8201601f810184136128b9575f80fd5b6124ba84823560208401612830565b5f602082840312156128d8575f80fd5b813565ffffffffffff81168114612196575f80fd5b6001600160a01b0391909116815260200190565b5f82601f830112612910575f80fd5b61219683833560208501612830565b5f8060408385031215612930575f80fd5b823561293b8161270e565b915060208301356001600160401b03811115612955575f80fd5b61296185828601612901565b9150509250929050565b5f8083601f84011261297b575f80fd5b5081356001600160401b03811115612991575f80fd5b6020830191508360208260051b85010111156129ab575f80fd5b9250929050565b5f805f805f805f806080898b0312156129c9575f80fd5b88356001600160401b03808211156129df575f80fd5b6129eb8c838d0161296b565b909a50985060208b0135915080821115612a03575f80fd5b612a0f8c838d0161296b565b909850965060408b0135915080821115612a27575f80fd5b612a338c838d0161296b565b909650945060608b0135915080821115612a4b575f80fd5b50612a588b828c0161296b565b999c989b5096995094979396929594505050565b8015158114610b6f575f80fd5b5f60208284031215612a89575f80fd5b813561219681612a6c565b5f82601f830112612aa3575f80fd5b813560206001600160401b0380831115612abf57612abf6127ec565b8260051b612ace838201612800565b9384528581018301938381019088861115612ae7575f80fd5b84880192505b85831015612b2157823584811115612b03575f80fd5b612b118a87838c0101612901565b8352509184019190840190612aed565b98975050505050505050565b5f805f805f805f805f805f60c08c8e031215612b47575f80fd5b6001600160401b03808d351115612b5c575f80fd5b612b698e8e358f0161296b565b909c509a5060208d0135811015612b7e575f80fd5b612b8e8e60208f01358f0161296b565b909a50985060408d0135811015612ba3575f80fd5b612bb38e60408f01358f0161296b565b909850965060608d0135811015612bc8575f80fd5b612bd88e60608f01358f0161296b565b909650945060808d0135811015612bed575f80fd5b612bfd8e60808f01358f0161296b565b909450925060a08d0135811015612c12575f80fd5b50612c238d60a08e01358e01612a94565b90509295989b509295989b9093969950565b5f60408284031215612c45575f80fd5b50919050565b5f60208284031215612c5b575f80fd5b815161219681612a6c565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6121966020830184612c66565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561243a5761243a612d3e565b6001600160a01b039384168152919092166020820152604081019190915260600190565b5f60208284031215612d99575f80fd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b5f808335601e19843603018112612dc9575f80fd5b8301803591506001600160401b03821115612de2575f80fd5b6020019150600581901b36038213156129ab575f80fd5b6001600160a01b03858116825284166020820152604081018390526080606082018190525f9061266790830184612c66565b5f65ffffffffffff80841680612e4f57634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b65ffffffffffff818116838216028082169190828114612e7d57612e7d612d3e565b505092915050565b65ffffffffffff828116828216039080821115612ea457612ea4612d3e565b5092915050565b65ffffffffffff818116838216019080821115612ea457612ea4612d3e565b5f82518060208501845e5f92019182525091905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220fbb86b087894762f1cc5e328c56a399114019bb4c9717baae1ef7b5a6a8680c164736f6c63430008190033496e697469616c697a61626c653a20636f6e747261637420697320616c7265617f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498
Deployed Bytecode
0x6080604052600436106101cb575f3560e01c8063623b9e9d116100f55780639fb67b581161008e5780639fb67b58146105f5578063b4a0bdf314610614578063bdac7ca314610633578063c4d66de814610652578063c748d26114610671578063cce80e7a14610690578063d9c98087146106bf578063e57480e5146106de578063fd54b22814610709575f80fd5b8063623b9e9d146104bd57806368508c98146104dc5780636ac56103146104fb57806371ee95c01461051a5780637be1c8f8146105395780637ee84349146105705780638237e5381461058f57806389e1e82a146105c257806395788835146105e1575f80fd5b80633a5345ab116101675780633a5345ab146103795780634641fdef1461038d57806349590657146103ac5780634d272d95146103c05780634f1ef2861461040c57806352d1902d1461041f5780635bf31d4d146104335780635cec892a1461046f5780635d3ea8f114610494575f80fd5b806309454ba3146101cf5780630c9cbf0e146101f75780630d10fca31461027b5780631171bda91461029c57806314769142146102bb57806314c8d37d146102e65780632637588e146103055780632a25dd411461033b5780633659cfe61461035a575b5f80fd5b3480156101da575f80fd5b506101e4606c5481565b6040519081526020015b60405180910390f35b348015610202575f80fd5b5061024f610211366004612722565b606d60209081525f9283526040808420909152908252902080546001909101546001600160d01b03821691600160d01b900465ffffffffffff169083565b604080516001600160d01b03909416845265ffffffffffff9092166020840152908201526060016101ee565b348015610286575f80fd5b5061029a610295366004612759565b610723565b005b3480156102a7575f80fd5b5061029a6102b6366004612770565b610815565b3480156102c6575f80fd5b506101e46102d53660046127ae565b606f6020525f908152604090205481565b3480156102f1575f80fd5b5061029a6103003660046127c9565b610907565b348015610310575f80fd5b506101e461031f366004612722565b607060209081525f928352604080842090915290825290205481565b348015610346575f80fd5b5061029a610355366004612884565b6109e6565b348015610365575f80fd5b5061029a6103743660046127ae565b610aa2565b348015610384575f80fd5b5061029a610b72565b348015610398575f80fd5b5061029a6103a73660046128c8565b610c3b565b3480156103b7575f80fd5b506101e4610d1c565b3480156103cb575f80fd5b506103ff6103da366004612722565b607260209081525f92835260408084209091529082529020546001600160a01b031681565b6040516101ee91906128ed565b61029a61041a36600461291f565b610d5e565b34801561042a575f80fd5b506101e4610e17565b34801561043e575f80fd5b50606b5461045890600160d01b900465ffffffffffff1681565b60405165ffffffffffff90911681526020016101ee565b34801561047a575f80fd5b50606b5461045890600160a01b900465ffffffffffff1681565b34801561049f575f80fd5b506104a8610ec3565b60405163ffffffff90911681526020016101ee565b3480156104c8575f80fd5b5061029a6104d73660046127ae565b610ee2565b3480156104e7575f80fd5b5061029a6104f6366004612722565b610fe1565b348015610506575f80fd5b50606b546103ff906001600160a01b031681565b348015610525575f80fd5b5061029a6105343660046129b2565b611048565b348015610544575f80fd5b50607154610558906001600160801b031681565b6040516001600160801b0390911681526020016101ee565b34801561057b575f80fd5b5061029a61058a3660046127ae565b6110fa565b34801561059a575f80fd5b506101e47f41263d2f619e70e9cb211899844b4cf7322f9939361a152780541ef1d2031cb681565b3480156105cd575f80fd5b5061029a6105dc366004612a79565b611203565b3480156105ec575f80fd5b5061029a611379565b348015610600575f80fd5b5061029a61060f366004612b2d565b611439565b34801561061f575f80fd5b50606a546103ff906001600160a01b031681565b34801561063e575f80fd5b5061029a61064d366004612722565b61148b565b34801561065d575f80fd5b5061029a61066c3660046127ae565b6115e0565b34801561067c575f80fd5b506069546103ff906001600160a01b031681565b34801561069b575f80fd5b506067546068546106aa919082565b604080519283526020830191909152016101ee565b3480156106ca575f80fd5b5061029a6106d9366004612c35565b611726565b3480156106e9575f80fd5b506101e46106f83660046127ae565b606e6020525f908152604090205481565b348015610714575f80fd5b506065546066546106aa919082565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b8906107539033906004016128ed565b602060405180830381865afa15801561076e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107929190612c4b565b6107af57604051633b8d9d7560e21b815260040160405180910390fd5b606b546001600160a01b0316156107d957604051630160c95d60e21b815260040160405180910390fd5b606c8190556040518181527f39bb629f3d59f5eddf978050e1f5fabeca2b5d02dfc9c25e84f32e7da1069db4906020015b60405180910390a150565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b8906108459033906004016128ed565b602060405180830381865afa158015610860573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108849190612c4b565b6108a157604051633b8d9d7560e21b815260040160405180910390fd5b6108b56001600160a01b03841683836118ac565b816001600160a01b0316836001600160a01b03167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b648836040516108fa91815260200190565b60405180910390a3505050565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b8906109379033906004016128ed565b602060405180830381865afa158015610952573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109769190612c4b565b61099357604051633b8d9d7560e21b815260040160405180910390fd5b607180546001600160e01b0316600160e01b63ffffffff8416908102919091179091556040519081527f83b318614a148a5806087ebf98a15a44e2a3fd3f57b829f39f4396c53c6b8cc39060200161080a565b606b546001600160a01b031615610a1057604051630160c95d60e21b815260040160405180910390fd5b606b54600160a01b900465ffffffffffff164210610a4157604051631a8f039560e01b815260040160405180910390fd5b606c54606954610a60916001600160a01b039091169033903090611914565b606b80546001600160a01b031916331790556040517f5eca00b8ed745eee61451333090bfa56aa1f2a9e696a2aebe5f1f5b6cef6f2ff9061080a908390612c94565b6001600160a01b037f000000000000000000000000918261fa5dd9c3b1358ca911792e9bdf3c5cca35163003610af35760405162461bcd60e51b8152600401610aea90612ca6565b60405180910390fd5b7f000000000000000000000000918261fa5dd9c3b1358ca911792e9bdf3c5cca356001600160a01b0316610b2561193b565b6001600160a01b031614610b4b5760405162461bcd60e51b8152600401610aea90612cf2565b610b5481611956565b604080515f80825260208201909252610b6f91839190611a0e565b50565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b890610ba29033906004016128ed565b602060405180830381865afa158015610bbd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610be19190612c4b565b610bfe57604051633b8d9d7560e21b815260040160405180910390fd5b607180546001600160801b03191660011790556040517fba5b67b940ab06d91fe570b3522545e329c2d970f23e0b6453e76431724402c9905f90a1565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b890610c6b9033906004016128ed565b602060405180830381865afa158015610c86573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610caa9190612c4b565b610cc757604051633b8d9d7560e21b815260040160405180910390fd5b606b80546001600160d01b0316600160d01b65ffffffffffff8416908102919091179091556040519081527ffdf22e84af74bd4ab6b9646f6370a02bc886ed6ac25882db14e4ebf4b8e3bc7e9060200161080a565b606b545f90600160a01b900465ffffffffffff164210801590610d485750606b546001600160a01b0316155b15610d54575060655490565b5060675490565b90565b6001600160a01b037f000000000000000000000000918261fa5dd9c3b1358ca911792e9bdf3c5cca35163003610da65760405162461bcd60e51b8152600401610aea90612ca6565b7f000000000000000000000000918261fa5dd9c3b1358ca911792e9bdf3c5cca356001600160a01b0316610dd861193b565b6001600160a01b031614610dfe5760405162461bcd60e51b8152600401610aea90612cf2565b610e0782611956565b610e1382826001611a0e565b5050565b5f306001600160a01b037f000000000000000000000000918261fa5dd9c3b1358ca911792e9bdf3c5cca351614610eb15760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c6044820152771b1959081d1a1c9bdd59da0819195b1959d85d1958d85b1b60421b6064820152608401610aea565b505f80516020612ee183398151915290565b607154600160e01b900463ffffffff165f819003610d5b5750610e1090565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b890610f129033906004016128ed565b602060405180830381865afa158015610f2d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f519190612c4b565b610f6e57604051633b8d9d7560e21b815260040160405180910390fd5b606b546001600160a01b031615610f9857604051630160c95d60e21b815260040160405180910390fd5b606980546001600160a01b0319166001600160a01b0383169081179091556040517f1db8d6629941dcb63d5e0c927b89c174c714e139a4b9107a49de839d755f5d74905f90a250565b335f8181526072602090815260408083206001600160a01b038681168086529190935281842080546001600160a01b03191693881693841790559051909391927f65e683f3800bc24dc7a30e42fb2e833290a4725be8b3658038a3f5d502f3d29f91a45050565b5f876001600160401b03811115611061576110616127ec565b60405190808252806020026020018201604052801561108a578160200160208202803683370190505b5090505f886001600160401b038111156110a6576110a66127ec565b6040519080825280602002602001820160405280156110d957816020015b60608152602001906001900390816110c45790505b5090506110ee8a8a8a8a8a8a8a8a8a8a611b78565b50505050505050505050565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b89061112a9033906004016128ed565b602060405180830381865afa158015611145573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111699190612c4b565b61118657604051633b8d9d7560e21b815260040160405180910390fd5b6001600160a01b0381165f908152606e60205260408120546111a9906001612d52565b6001600160a01b0383165f818152606e6020908152604091829020849055905160018414815292935090917f7628ea5f6112a16b36a8239aa208395a8e8f221688cfb3a5461faffb9700abcd910160405180910390a25050565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b8906112339033906004016128ed565b602060405180830381865afa15801561124e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112729190612c4b565b61128f57604051633b8d9d7560e21b815260040160405180910390fd5b606b546001600160a01b03166112b85760405163126ea8e960e31b815260040160405180910390fd5b80156112ec57606b54606c546069546112df926001600160a01b03918216929116906118ac565b6112e7612069565b611337565b606c54606954611309916001600160a01b039091169033906118ac565b6113124261213a565b606b60146101000a81548165ffffffffffff021916908365ffffffffffff1602179055505b606b80546001600160a01b031916905560405181151581527f8015c5005d9ad5d85ca80d3f894f08e0159277704c54166e5cff108800fa80cd9060200161080a565b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b8906113a99033906004016128ed565b602060405180830381865afa1580156113c4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113e89190612c4b565b61140557604051633b8d9d7560e21b815260040160405180910390fd5b606b546001600160a01b03161561142f57604051630160c95d60e21b815260040160405180910390fd5b611437612069565b565b61147e8b8b8b8b8b8b8b8b8b8b808060200260200160405190810160405280939291908181526020018383602002808284375f920191909152508d9250611b78915050565b5050505050505050505050565b816001600160a01b03811633148015906114b45750335f908152606e6020526040902054600114155b801561152c5750606a5460405163521d4de960e01b81526001600160a01b039091169063521d4de9906114eb9033906004016128ed565b602060405180830381865afa158015611506573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061152a9190612c4b565b155b1561154a57604051636115324760e11b815260040160405180910390fd5b6001600160a01b038084165f9081526070602090815260408083209386168352929052205461157a816001612d52565b6001600160a01b038581165f81815260706020908152604080832094891680845294825291829020949094555184158152919290917f42343f44c66ea1eaffa334760d3da2cb731d2a0b3b3e30423df997faa36cc95c910160405180910390a350505050565b5f54610100900460ff16158080156115fe57505f54600160ff909116105b806116175750303b15801561161757505f5460ff166001145b61167a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610aea565b5f805460ff19166001179055801561169b575f805461ff0019166101001790555b6001600160a01b0382166116c25760405163d92e233d60e01b815260040160405180910390fd5b606a80546001600160a01b0319166001600160a01b0384161790558015610e13575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15050565b606b546001600160a01b03161515806117e05750335f908152606e602052604090205460011415806117685750606b54600160a01b900465ffffffffffff1642105b80156117e05750606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b89061179f9033906004016128ed565b602060405180830381865afa1580156117ba573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117de9190612c4b565b155b156117fe57604051636115324760e11b815260040160405180910390fd5b604080518082019091526065805480835260668054602080860182905286359094559285013590556067556068555f6118364261213a565b606b805465ffffffffffff60a01b1916600160a01b65ffffffffffff841690810291909117909155604080518635815260208088013590820152908101919091529091507f23aa2e4f757a7bd974085d3e11439a843b137b30905e3ffd51b2097c34aef62e9060600160405180910390a1505050565b6040516001600160a01b03831660248201526044810182905261190f90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261219d565b505050565b611935846323b872dd60e01b8585856040516024016118d893929190612d65565b50505050565b5f80516020612ee1833981519152546001600160a01b031690565b6071546001600160801b03166001036119825760405163229b36d360e01b815260040160405180910390fd5b606a54604051631c86b03760e31b81526001600160a01b039091169063e43581b8906119b29033906004016128ed565b602060405180830381865afa1580156119cd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119f19190612c4b565b610b6f57604051633b8d9d7560e21b815260040160405180910390fd5b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615611a415761190f83612270565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611a9b575060408051601f3d908101601f19168201909252611a9891810190612d89565b60015b611afe5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610aea565b5f80516020612ee18339815191528114611b6c5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610aea565b5061190f83838361230b565b607154600160801b90046bffffffffffffffffffffffff16600203611bb0576040516306fda65d60e31b815260040160405180910390fd5b60718054600160801b600160e01b031916600160811b17905588801580611bd75750808814155b80611be25750808614155b80611bed5750808414155b80611bf9575082518114155b80611c05575081518114155b15611c2357604051631df89e8b60e01b815260040160405180910390fd5b5f5b81811015612042575f8c8c83818110611c4057611c40612da0565b9050602002016020810190611c5591906127ae565b90505f8b8b84818110611c6a57611c6a612da0565b9050602002016020810190611c7f91906127ae565b90505f8a8a85818110611c9457611c94612da0565b9050602002013590505f868581518110611cb057611cb0612da0565b60200260200101519050836001600160a01b0316336001600160a01b031614158015611ce55750326001600160a01b03851614155b8015611d1157506001600160a01b0384165f908152607060209081526040808320338452909152902054155b15611d2f57604051630b094f2760e31b815260040160405180910390fd5b5f848484604051602001611d4593929190612d65565b604051602081830303815290604052805190602001209050611dbb818c8c89818110611d7357611d73612da0565b9050602002810190611d859190612db4565b808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525061232f92505050565b611dd8576040516309bde33960e01b815260040160405180910390fd5b6001600160a01b038086165f908152606d60209081526040808320938816835292905290812054611e12906001600160d01b031685612d52565b90506040518060600160405280611e2886612440565b6001600160d01b031681526020014265ffffffffffff168152602001611e4c610d1c565b90526001600160a01b038781165f818152606d60209081526040808320948b168084529482529182902085518683015165ffffffffffff16600160d01b026001600160d01b039091161781559482015160019095019490945551848152919290917ff7a40077ff7a04c7e61f6f26fb13774259ddf1b6bce9ecf26a8276cdd3992683910160405180910390a35f8a8881518110611eeb57611eeb612da0565b60200260200101519050866001600160a01b0316336001600160a01b0316141580611f1d57506001600160a01b038116155b15611f5c576001600160a01b038088165f9081526072602090815260408083208a851684529091529020541680611f5657879150611f5a565b8091505b505b811561203057611f766001600160a01b03871682846118ac565b83511561203057604051635f20da2d60e01b81526001600160a01b03821690635f20da2d90611faf908a908a908a908a90600401612df9565b6020604051808303815f875af1925050508015611fe9575060408051601f3d908101601f19168201909252611fe691810190612d89565b60015b15612030577f41263d2f619e70e9cb211899844b4cf7322f9939361a152780541ef1d2031cb6811461202e5760405163ee418e3760e01b815260040160405180910390fd5b505b87600101975050505050505050611c25565b505060718054600160801b600160e01b031916600160801b17905550505050505050505050565b6040805180820190915260675480825260685460208301819052606b805465ffffffffffff60a01b191690556065919091556066555f6120a7610ec3565b6040519091507f44825a4b2df8acb19ce4e1afba9aa850c8b65cdb7942e2078f27d0b0960efee6905f90a1815160208301517f23aa2e4f757a7bd974085d3e11439a843b137b30905e3ffd51b2097c34aef62e919063ffffffff841661210d8142612e2b565b6121179190612e5b565b60408051938452602084019290925265ffffffffffff169082015260600161171a565b5f80612144610ec3565b606b5490915063ffffffff821690600160d01b900465ffffffffffff168161216d600187612e85565b6121779190612e2b565b612182906001612eab565b61218c9190612eab565b6121969190612e5b565b9392505050565b5f6121f1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166124ac9092919063ffffffff16565b905080515f14806122115750808060200190518101906122119190612c4b565b61190f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610aea565b6001600160a01b0381163b6122dd5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610aea565b5f80516020612ee183398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b612314836124c2565b5f825111806123205750805b1561190f576119358383612501565b80515f908390825b818110156124085784818151811061235157612351612da0565b60200260200101518310156123b2578285828151811061237357612373612da0565b6020026020010151604051602001612395929190918252602082015260400190565b604051602081830303815290604052805190602001209250612400565b8481815181106123c4576123c4612da0565b6020026020010151836040516020016123e7929190918252602082015260400190565b6040516020818303038152906040528051906020012092505b600101612337565b505f612412610d1c565b905080612432576040516301295acb60e31b815260040160405180910390fd5b919091149150505b92915050565b5f6001600160d01b038211156124a85760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663038206269747360c81b6064820152608401610aea565b5090565b60606124ba84845f85612526565b949350505050565b6124cb81612270565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a250565b60606121968383604051806060016040528060278152602001612f01602791396125fd565b6060824710156125875760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610aea565b5f80866001600160a01b031685876040516125a29190612eca565b5f6040518083038185875af1925050503d805f81146125dc576040519150601f19603f3d011682016040523d82523d5f602084013e6125e1565b606091505b50915091506125f287838387612671565b979650505050505050565b60605f80856001600160a01b0316856040516126199190612eca565b5f60405180830381855af49150503d805f8114612651576040519150601f19603f3d011682016040523d82523d5f602084013e612656565b606091505b509150915061266786838387612671565b9695505050505050565b606083156126df5782515f036126d8576001600160a01b0385163b6126d85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aea565b50816124ba565b6124ba83838151156126f45781518083602001fd5b8060405162461bcd60e51b8152600401610aea9190612c94565b6001600160a01b0381168114610b6f575f80fd5b5f8060408385031215612733575f80fd5b823561273e8161270e565b9150602083013561274e8161270e565b809150509250929050565b5f60208284031215612769575f80fd5b5035919050565b5f805f60608486031215612782575f80fd5b833561278d8161270e565b9250602084013561279d8161270e565b929592945050506040919091013590565b5f602082840312156127be575f80fd5b81356121968161270e565b5f602082840312156127d9575f80fd5b813563ffffffff81168114612196575f80fd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715612828576128286127ec565b604052919050565b5f6001600160401b03831115612848576128486127ec565b61285b601f8401601f1916602001612800565b905082815283838301111561286e575f80fd5b828260208301375f602084830101529392505050565b5f60208284031215612894575f80fd5b81356001600160401b038111156128a9575f80fd5b8201601f810184136128b9575f80fd5b6124ba84823560208401612830565b5f602082840312156128d8575f80fd5b813565ffffffffffff81168114612196575f80fd5b6001600160a01b0391909116815260200190565b5f82601f830112612910575f80fd5b61219683833560208501612830565b5f8060408385031215612930575f80fd5b823561293b8161270e565b915060208301356001600160401b03811115612955575f80fd5b61296185828601612901565b9150509250929050565b5f8083601f84011261297b575f80fd5b5081356001600160401b03811115612991575f80fd5b6020830191508360208260051b85010111156129ab575f80fd5b9250929050565b5f805f805f805f806080898b0312156129c9575f80fd5b88356001600160401b03808211156129df575f80fd5b6129eb8c838d0161296b565b909a50985060208b0135915080821115612a03575f80fd5b612a0f8c838d0161296b565b909850965060408b0135915080821115612a27575f80fd5b612a338c838d0161296b565b909650945060608b0135915080821115612a4b575f80fd5b50612a588b828c0161296b565b999c989b5096995094979396929594505050565b8015158114610b6f575f80fd5b5f60208284031215612a89575f80fd5b813561219681612a6c565b5f82601f830112612aa3575f80fd5b813560206001600160401b0380831115612abf57612abf6127ec565b8260051b612ace838201612800565b9384528581018301938381019088861115612ae7575f80fd5b84880192505b85831015612b2157823584811115612b03575f80fd5b612b118a87838c0101612901565b8352509184019190840190612aed565b98975050505050505050565b5f805f805f805f805f805f60c08c8e031215612b47575f80fd5b6001600160401b03808d351115612b5c575f80fd5b612b698e8e358f0161296b565b909c509a5060208d0135811015612b7e575f80fd5b612b8e8e60208f01358f0161296b565b909a50985060408d0135811015612ba3575f80fd5b612bb38e60408f01358f0161296b565b909850965060608d0135811015612bc8575f80fd5b612bd88e60608f01358f0161296b565b909650945060808d0135811015612bed575f80fd5b612bfd8e60808f01358f0161296b565b909450925060a08d0135811015612c12575f80fd5b50612c238d60a08e01358e01612a94565b90509295989b509295989b9093969950565b5f60408284031215612c45575f80fd5b50919050565b5f60208284031215612c5b575f80fd5b815161219681612a6c565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6121966020830184612c66565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561243a5761243a612d3e565b6001600160a01b039384168152919092166020820152604081019190915260600190565b5f60208284031215612d99575f80fd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b5f808335601e19843603018112612dc9575f80fd5b8301803591506001600160401b03821115612de2575f80fd5b6020019150600581901b36038213156129ab575f80fd5b6001600160a01b03858116825284166020820152604081018390526080606082018190525f9061266790830184612c66565b5f65ffffffffffff80841680612e4f57634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b65ffffffffffff818116838216028082169190828114612e7d57612e7d612d3e565b505092915050565b65ffffffffffff828116828216039080821115612ea457612ea4612d3e565b5092915050565b65ffffffffffff818116838216019080821115612ea457612ea4612d3e565b5f82518060208501845e5f92019182525091905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220fbb86b087894762f1cc5e328c56a399114019bb4c9717baae1ef7b5a6a8680c164736f6c63430008190033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.