Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 99 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Whitelist | 20433630 | 32 days ago | IN | 0 ETH | 0.00040617 | ||||
Whitelist | 20376355 | 40 days ago | IN | 0 ETH | 0.0001913 | ||||
Grant Role | 20368889 | 42 days ago | IN | 0 ETH | 0.00036693 | ||||
Revoke Role | 20368456 | 42 days ago | IN | 0 ETH | 0.00015357 | ||||
Grant Role | 20368438 | 42 days ago | IN | 0 ETH | 0.00040757 | ||||
Revoke Role | 20368430 | 42 days ago | IN | 0 ETH | 0.00016566 | ||||
Distribute | 20368067 | 42 days ago | IN | 0 ETH | 0.00082652 | ||||
Distribute | 20360964 | 43 days ago | IN | 0 ETH | 0.00050273 | ||||
Distribute | 20353746 | 44 days ago | IN | 0 ETH | 0.00035332 | ||||
Distribute | 20346590 | 45 days ago | IN | 0 ETH | 0.000518 | ||||
Distribute | 20339415 | 46 days ago | IN | 0 ETH | 0.00073609 | ||||
Distribute | 20332241 | 47 days ago | IN | 0 ETH | 0.00099969 | ||||
Whitelist | 20326892 | 47 days ago | IN | 0 ETH | 0.00126355 | ||||
Distribute | 20325068 | 48 days ago | IN | 0 ETH | 0.0013761 | ||||
Distribute | 20317896 | 49 days ago | IN | 0 ETH | 0.0009758 | ||||
Distribute | 20310725 | 50 days ago | IN | 0 ETH | 0.00048699 | ||||
Distribute | 20303561 | 51 days ago | IN | 0 ETH | 0.00046405 | ||||
Distribute | 20296386 | 52 days ago | IN | 0 ETH | 0.00029674 | ||||
Distribute | 20289224 | 53 days ago | IN | 0 ETH | 0.00044971 | ||||
Distribute | 20282065 | 54 days ago | IN | 0 ETH | 0.00056859 | ||||
Distribute | 20274906 | 55 days ago | IN | 0 ETH | 0.0005815 | ||||
Distribute | 20267756 | 56 days ago | IN | 0 ETH | 0.00040734 | ||||
Distribute | 20260604 | 57 days ago | IN | 0 ETH | 0.00065439 | ||||
Distribute | 20253456 | 58 days ago | IN | 0 ETH | 0.00027653 | ||||
Whitelist | 20248648 | 58 days ago | IN | 0 ETH | 0.00018984 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
MPROMasterDistributor
Compiler Version
v0.8.22+commit.4fc1097e
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/utils/Context.sol"; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "hardhat/console.sol"; interface IMPRO is IERC20 { function mint(address account, uint256 amount) external; function maxCap() external pure returns (uint256); } /** * @title MPRO Master Distributor Contract * @dev The MPROMasterDistributor contract manages token distribution and related operations. * It is responsible for distributing tokens to eligible recipients based on specified rules and * configurations. This contract utilizes the AccessControl feature for role-based access control. * * This contract extends the Context and AccessControl contracts to leverage their functionality. * Role-based access control allows specific roles to perform authorized actions within the contract, * ensuring proper governance and security. */ contract MPROMasterDistributor is Context, AccessControl, Ownable { using SafeMath for uint256; /** * @dev Struct representing a distribution reduction configuration. * * This struct defines a configuration for reducing the daily token distribution over time. It * consists of two fields: * - `reductionTimestamp`: The timestamp at which the reduction in distribution should take effect. * - `daylyDistribution`: The daily distribution amount of tokens after the reduction. * * Instances of this struct are typically used in an array to specify different reduction * configurations over time. The reduction timestamp marks when the daily distribution amount * should change. */ struct DistributionReduction { uint256 reductionTimestamp; uint256 daylyDistribution; } /** * @dev Constant representing the number of seconds in a day. * * This constant defines the number of seconds in a day, which is used for time calculations * within the contract. It is set to the standard value of 86,400 seconds per day. */ uint256 constant SECONDS_PER_DAY = 86400; bytes32 public constant MPRO_MASTER_DISTRIBUTOR_ROLE = keccak256("MPRO_MASTER_DISTRIBUTOR_ROLE"); bytes32 public constant DISTRIBUTIONS_ADMINISTRATOR_ROLE = keccak256("DISTRIBUTIONS_ADMINISTRATOR_ROLE"); bytes32 public constant DISTRIBUTIONS_ADMINISTRATOR_ROLE_MANAGER = keccak256("DISTRIBUTIONS_ADMINISTRATOR_ROLE_MANAGER"); bytes32 public constant LISTER_ROLE = keccak256("LISTER_ROLE"); IMPRO private mproToken; mapping(bytes32 => bool) private assignedRoles; /** * @dev Internal mapping to manage blocklisted addresses. * * This mapping associates addresses (keys) with boolean values to maintain a list of addresses * that are considered "blocklisted" within the contract's logic. If an address is included in * this mapping with a `true` value, it indicates that the address is blocklisted and may be * subject to certain restrictions or limitations imposed by the contract. * * The mapping is typically used in access control mechanisms and other parts of the contract's * logic to determine the behavior or privileges associated with addresses based on their * blocklist status. */ mapping(address => bool) internal blocklisted; /** * @dev Internal mapping to manage whitelisted addresses. * * This mapping associates addresses (keys) with boolean values to maintain a list of addresses * that are considered "whitelisted" within the contract's logic. If an address is included in * this mapping with a `true` value, it indicates that the address is whitelisted and may have * special privileges or exemptions within the contract. * * The mapping is typically used in access control mechanisms and other parts of the contract's * logic to determine the behavior or privileges associated with addresses based on their * whitelist status. */ mapping(address => bool) internal whitelisted; /** * @dev Timestamp indicating when token distribution starts. * * This private state variable stores the Unix timestamp (in seconds) that marks the beginning * of the token distribution period. The value is set during the contract initialization and * can be updated by specific functions within the contract, depending on the contract's logic. * * The distributionStartTimestamp is used in various functions to determine whether the * distribution period has begun. This allows for conditional logic based on the time, such as * enabling token distributions only after this timestamp is reached. * * Being a private variable, it can only be accessed and modified by functions within this * contract, providing a controlled and secure way to manage the start of the distribution phase. */ uint256 public distributionStartTimestamp; /** * @dev Private immutable variable representing the deadline for the distribution start timestamp. * * This variable is used to store an immutable timestamp that defines the deadline for the * distribution start timestamp within the contract. It is typically set during contract * initialization and remains constant throughout the contract's lifetime. * * The distribution start timestamp deadline indicates the latest permissible timestamp for * starting the distribution of tokens. After this deadline, distribution start timestamps * beyond this value will not be accepted. */ uint256 private immutable distributionStartTimestampDeadLine; /** * @dev Private variable to keep track of the total tokens distributed. * * This variable is used to maintain a count of the total tokens that have been distributed * within the contract. It starts at zero and is updated whenever tokens are distributed to * recipients. * * It serves as a record of the cumulative tokens distributed and is often used to enforce * distribution limits or to check the available tokens for distribution. */ uint256 private distributedTokens; /** * @dev Private constant representing the initial daily distribution of tokens. * * This constant defines the initial daily distribution of tokens within the contract. It * represents a fixed amount of tokens that are distributed daily as part of a distribution * mechanism. * * The value is expressed in the contract's token decimals, and it remains constant throughout * the contract's lifetime. */ uint256 public constant initialDaylyDistribution = 250_000 * 10 ** 18; /** * @dev Public array to store distribution reduction configurations. * * This dynamic array stores instances of the `DistributionReduction` struct, representing * configurations for reducing the daily token distribution over time. Each element of the array * specifies a different reduction configuration, and the array can grow as more configurations * are added. * * These configurations determine when and how the daily distribution amount of tokens changes * over time, allowing for flexibility in managing token distribution within the contract. */ DistributionReduction[] private distributionReductions; /** * @dev Public variable representing the burn rate for tokens. * * This variable determines the burn rate for tokens within the contract, expressed as a * percentage. A burn rate of 1000 corresponds to 10%, where a portion of tokens is burned * during certain operations. A burn rate of 10000 would represent 100%. * * The value of this variable can be adjusted to control the rate at which tokens are burned * during specific actions, impacting the total token supply over time. */ uint256 public burnRate = 1000; // 10000 = 100% /** * @dev Modifier to check and enable distribution reduction configurations. * * This modifier is used to validate and enable distribution reduction configurations. It checks * that the provided `_reductionTimestamp` and `_reductionAmount` meet certain criteria to ensure * that reductions are allowed. The criteria include: * * - `_reductionTimestamp` must be greater than the timestamp of the last reduction. * - `_reductionTimestamp` must be greater than or equal to the current timestamp plus 30 days. * - `_reductionAmount` must be greater than or equal to half of the previous daily distribution. * * If all criteria are met, the modifier allows the decorated function or operation to proceed. * Otherwise, it reverts with specific error messages. */ event Distributed(address indexed _to, uint256 amount); event SetDistribiutionStartTime(uint256 _startTime); event AddDistributionReduction( uint256 _redutionTimestamp, uint256 _reductionAmount ); event SetMPRO(address _mproTokenAddress); event SetBurnRate(uint256 _burnRate); event SetDistributorTimeAdministratorRoleManager( address _roleManagerAddress ); event SetDistributorTimeAdministratorRole(address _roleManagerAddress); /** * @dev Modifier that enforces rules for reduction in distribution. It ensures that a new distribution * reduction can only be set after a certain period from the last reduction, and the new reduction amount * must be within specific limits compared to the last reduction amount. * * The modifier checks against the last entry in the `distributionReductions` array (if it exists) to * enforce the following: * 1. The new reduction timestamp must be at least 183 days after the last reduction's timestamp. * 2. The new daily distribution amount must not be more than half of the last reduction's daily distribution. * 3. The new daily distribution amount must not be more than the last reduction's daily distribution multiplied by 2. * * This ensures a controlled and limited reduction of distribution over time. * * @param _reductionTimestamp The timestamp when the new reduction is intended to start. * @param _reductionAmount The new daily distribution amount after the reduction. */ modifier reductionEnabled( uint256 _reductionTimestamp, uint256 _reductionAmount ) { DistributionReduction memory lastReduction; if (distributionReductions.length > 0) { lastReduction = distributionReductions[ distributionReductions.length - 1 ]; } else { lastReduction = DistributionReduction( distributionStartTimestamp, initialDaylyDistribution ); } require( _reductionTimestamp >= lastReduction.reductionTimestamp + 183 days, "MPROMasterDistributor: New redution start time cannot be lower than 183 days after last redution timestamp" ); require( _reductionAmount >= lastReduction.daylyDistribution.div(2), "MPROMasterDistributor: New reduction amount cannot be greater than half of the last reduction amount" ); require( _reductionAmount <= lastReduction.daylyDistribution.mul(2), "MPROMasterDistributor: New reduction amount cannot be greater than the last reduction amount multiplied by 2" ); _; } /** * @dev Modifier to ensure that the provided address is not blocklisted. * * This modifier is used to validate that the `_account` address passed as an argument is not * blocklisted within the contract. Addresses that are blocklisted may have certain restrictions * or limitations imposed on them by the contract, and this modifier helps prevent blocklisted * addresses from participating in specific operations. * * If the `_account` address is blocklisted, the contract will revert with the message "MPROMasterDistributor: Action on blocklisted account" * If the address is not blocklisted, the modified function or operation is executed as intended. */ modifier notBlocklisted(address _account) { require( !blocklisted[_account], "MPROMasterDistributor: Action on blocklisted account" ); _; } /** * @dev Modifier to ensure that the provided address is not the zero address. * * This modifier is used to validate that the `_account` address passed as an argument is not * equal to the zero address (`address(0)`). Preventing the zero address from being used in * certain contexts can help avoid unexpected behavior, as the zero address often has special * significance. * * If the `_account` address is the zero address, the contract will revert with the error code "Action on address zero" * If the address is valid (not zero), the modified function or operation is executed. */ modifier notZeroAddress(address _account) { require( _account != address(0), "MPROMasterDistributor: Action on address zero" ); _; } /** * @dev Modifier that ensures a role has not already been assigned to an account. This modifier checks * the status of a role in the `assignedRoles` mapping. If the role has already been granted (i.e., the * corresponding value in the mapping is `true`), the function call is reverted with an error message. * This is used to prevent roles from being granted to more than one account, ensuring unique assignment * of responsibilities or permissions within the contract. * * @param _role The bytes32 identifier of the role to check. */ modifier notGranted(bytes32 _role) { require( !assignedRoles[_role], "MPROMasterDistributor: Role already granted to another account" ); _; } /** * @dev Modifier that checks if a role has not been marked as burned. A role is considered burned if * it has been explicitly revoked and cannot be reassigned. This is typically done by assigning the role * to the zero address. The modifier uses the `hasRole` function to check the status of the role. * If the role is found to be assigned to the zero address, indicating that it has been burned, the * function call is reverted with an error message. This prevents operations on roles that are meant to * be permanently inactive or revoked. * * @param _role The bytes32 identifier of the role to check. */ modifier notBurned(bytes32 _role) { require( !hasRole(_role, address(0)), "MPROMasterDistributor: Role is already burned" ); _; } /** * @dev Constructor for the contract. Initializes the contract by setting the distribution start timestamp, * the distribution deadline, and assigning the OWNER_ROLE to the provided owner address. The distribution * start timestamp is set to 14 days from the current block time, providing a preparation period before the * distribution begins. The distribution deadline is set to 30 days from the current block time, creating a * finite period for the distribution process. The OWNER_ROLE is crucial for contract administration and * oversight, allowing the owner to manage the contract's key operations. * * @param _owner The address that will be assigned the OWNER_ROLE, granting administrative control over the contract. */ constructor(address _owner) { // Set the distribution start timestamp to 14 days from the current block time. // This delay allows for a preparation period before the distribution begins. distributionStartTimestamp = block.timestamp + 14 days; // Set the deadline for the distribution period to 30 days from the current block time. // This sets a finite period for the distribution process, ensuring a clear end date. distributionStartTimestampDeadLine = block.timestamp + 30 days; // Assign the OWNER_ROLE to the provided owner address. This role typically includes // elevated privileges and is crucial for contract administration and oversight. _transferOwnership(_owner); } /** * @dev Calculates the total token distribution based on the initial daily distribution, the elapsed time, * and any distribution reductions that have been set. The function first checks if the current timestamp * is past the distribution start timestamp. If not, it returns 0, indicating that distribution has not * started yet. If the distribution has started, it calculates the total distribution by taking into * account the initial daily distribution and adjusting it based on any reductions that have occurred * since the start of the distribution. * * The function iterates through each distribution reduction, checks if the current timestamp is greater * than the reduction timestamp, and, if so, calculates the distribution for the time period since the last * reduction. It updates the total distribution accordingly. The total distribution also includes the * distribution for the period from the start timestamp until the first reduction or the current time, * whichever comes first. * * @return The total token distribution up to the current block timestamp. */ function getAllTokenDistribution() public view returns (uint256) { if (block.timestamp < distributionStartTimestamp) { return 0; } DistributionReduction[] memory _distributionReductions = distributionReductions; // Time periods since last distribution uint256 timeElapsed = block.timestamp - distributionStartTimestamp; // If days elapsed will return 0 and block.timestamp < distributionStartTimestamp we want to add initialDaylyDistribution to totalDistribution (step before loop with reductions) uint256 daysElapsed = timeElapsed / SECONDS_PER_DAY; uint256 totalDistribution; uint256 reductionEndTimestamp = block.timestamp; for ( uint256 index = _distributionReductions.length; index > 0; index-- ) { DistributionReduction memory distributionReduction = _distributionReductions[ index - 1 ]; // Check if the current timestamp is greater than the reduction timestamp if (block.timestamp >= distributionReduction.reductionTimestamp) { // Calculate the number of days in the current period uint256 daysInCurrentPeriod = (reductionEndTimestamp - distributionReduction.reductionTimestamp) / SECONDS_PER_DAY; totalDistribution += // for 1.01 day in distribution we need to add one daily distribution // For 0.1 days we will get daysInCurrentPeriod = 0, so we need to add already calculated part distributionReduction.daylyDistribution + (daysInCurrentPeriod * distributionReduction.daylyDistribution); // Update timestamp for previous period reductionEndTimestamp = distributionReduction .reductionTimestamp; // Update daysElapsed for previous period daysElapsed -= daysInCurrentPeriod; } } // When all reductions are calculated we need to add the rest of the days with the initialDaylyDistribution // We want to calulate distribution from the first second of the distribution start timestamp totalDistribution += initialDaylyDistribution + // When days elapsed is 0 we need to add initialDaylyDistribution since distribution starts from the first second of the distributionStartTimestamp daysElapsed * initialDaylyDistribution; return totalDistribution >= mproToken.maxCap() ? mproToken.maxCap() : totalDistribution; } /** * @dev Calculates the quantity of tokens that are available for distribution at the current time. * It determines this quantity by subtracting the total number of tokens already distributed * (`distributedTokens`) from the total number of tokens that should have been distributed up to the * current point in time (`getAllTokenDistribution`). This function provides insight into the remaining * token balance that is available for distribution, ensuring that the distribution does not exceed * the planned amount at any given point. * * Note that this is a private function and can only be called within the contract itself. This function * is typically used internally to manage and track the distribution process accurately. * * @return The quantity of tokens that are currently available for distribution. */ function getAvailableForDistributionTokenQuantity() private view returns (uint256) { return getAllTokenDistribution().sub(distributedTokens); } /** * @dev Distributes a specified amount of tokens to a given address. * * This function allows tokens to be minted and distributed to a specified address. * It can only be called by an account with the MPRO_MASTER_DISTRIBUTOR_ROLE. * The function performs several checks before proceeding with the distribution: * - It ensures that the amount to be distributed is greater than 0. * - It verifies that the current timestamp is greater than or equal to the distributionStartTimestamp, * ensuring that the distribution period has started. * - It checks that the total amount of tokens to be distributed (including the current distribution) * does not exceed the quantity available for distribution as determined by * getAvailableForDistributionTokenQuantity. * * If all checks pass, the function increments the distributedTokens state variable by the amount * to be distributed and calls the mint function on the mproToken contract to mint the tokens * to the specified address. * * @param _to The address to which the tokens will be distributed. * @param _amount The amount of tokens to be distributed. */ function distribute( address _to, uint256 _amount ) public onlyRole(MPRO_MASTER_DISTRIBUTOR_ROLE) { require(_amount > 0, "amount must be greater than 0"); require( block.timestamp >= distributionStartTimestamp, "MPROMasterDistributor: Distribution is not enabled yet" ); require( _amount <= getAvailableForDistributionTokenQuantity(), "MPROMasterDistributor: Distribution limit exceeded" ); mproToken.mint(_to, _amount); distributedTokens += _amount; emit Distributed(_to, _amount); } /** * @dev Distributes tokens to multiple addresses in bulk. * * This function allows for the bulk distribution of tokens to a list of addresses, each receiving * a specified amount. It is designed to efficiently handle multiple distributions in a single transaction. * The function can only be invoked by an account with the MPRO_MASTER_DISTRIBUTOR_ROLE. * * The function performs the following checks and operations: * - It ensures that the length of the `_to` address array matches the length of the `_amount` array, * ensuring each address has a corresponding amount to be distributed. * - It then iterates over these arrays, calling the `distribute` function for each address-amount pair. * The `distribute` function is responsible for the actual minting and transferring of tokens, * as well as performing necessary checks such as ensuring the distribution period has started and * that the total distributed amount does not exceed the available quantity. * * Note: This function relies on the `distribute` function for individual distributions and inherits * its checks and limitations. Each distribution in the loop is treated as a separate transaction in * terms of checks and effects. * * @param _to An array of addresses to which tokens will be distributed. * @param _amount An array of token amounts to be distributed to the respective addresses. */ function distributeBulk( address[] memory _to, uint256[] memory _amount ) public onlyRole(MPRO_MASTER_DISTRIBUTOR_ROLE) { require( _to.length == _amount.length, "to and amount arrays must have the same length" ); for (uint256 i = 0; i < _to.length; i++) { distribute(_to[i], _amount[i]); } } /** * @dev Sets a new distribution start time. * * This function allows the contract owner to set a new start time * for the token distribution process. It ensures that the new start time is in the future, has not yet been * surpassed, and is before the predefined distribution start timestamp deadline. This function can only be * called if the distribution has not yet started (i.e., no tokens have been distributed). * * The function includes checks to ensure: * 1. The distribution has not yet started (`distributedTokens` must be 0). * 2. The new start time (`_startTime`) is in the future (greater than the current `block.timestamp`). * 3. The new start time does not exceed the predefined deadline (`distributionStartTimestampDeadLine`). * * If all conditions are met, the function updates the `distributionStartTimestamp` and emits a * `SetDistribiutionStartTime` event with the new start time. * * @param _startTime The new start time for token distribution. */ function setDistributionStartTime(uint256 _startTime) external onlyOwner { require( distributedTokens == 0, "MPROMasterDistributor: Distribution start time cannot be changed after distribution has started" ); require( _startTime > block.timestamp, "MPROMasterDistributor: Distribution start time cannot be lower than current time" ); require( _startTime <= distributionStartTimestampDeadLine, "MPROMasterDistributor: Distribution start time must be less than distributionStartTimeDeadline" ); distributionStartTimestamp = _startTime; emit SetDistribiutionStartTime(_startTime); } /** * @dev Adds a new distribution reduction to the contract. * * This external function allows an account with the DISTRIBUTIONS_ADMINISTRATOR_ROLE to add a * new distribution reduction. A distribution reduction is a record that signifies a change in the * distribution amount of tokens from a specific timestamp. * * The function includes a modifier `reductionEnabled` which likely contains logic to validate the * input parameters `_redutionTimestamp` and `_reductionAmount`. It ensures that the reduction * parameters meet certain criteria before allowing the addition of the new reduction. * * Once validated, the function appends a new `DistributionReduction` struct to the * `distributionReductions` array. This struct includes the timestamp from which the reduction * should take effect (`_redutionTimestamp`) and the new amount to be distributed from that * timestamp (`_reductionAmount`). * * @param _redutionTimestamp The timestamp from which the new distribution amount should apply. * @param _reductionAmount The new amount to be distributed from the specified timestamp. */ function addDistributionReduction( uint256 _redutionTimestamp, uint256 _reductionAmount ) external onlyRole(DISTRIBUTIONS_ADMINISTRATOR_ROLE) reductionEnabled(_redutionTimestamp, _reductionAmount) { distributionReductions.push( DistributionReduction(_redutionTimestamp, _reductionAmount) ); emit AddDistributionReduction(_redutionTimestamp, _reductionAmount); } /** * @dev Sets the address of the MPRO token contract. This function allows the contract owner to set or * update the address of the MPRO token contract to be used in the distribution. It includes a check to ensure * that the MPRO token address is not already set, preventing accidental overwriting of the token address. * * This is a critical function as it establishes the link to the MPRO token that will be distributed by this * contract. The function can only be successfully called once, as the MPRO token address is intended to be * immutable once set to prevent unauthorized changes. * * If the token address has not been set before, the function updates the `mproToken` state variable and emits * a `SetMPRO` event with the new MPRO token address. * * @param _mproTokenAddress The address of the MPRO token contract to be set. */ function setMPRO(address _mproTokenAddress) external onlyOwner { require( mproToken == IMPRO(address(0)), "MPROMasterDistributor: MPRO token is already set" ); mproToken = IMPRO(_mproTokenAddress); emit SetMPRO(_mproTokenAddress); } /** * @dev Calculates the amount to be burned based on the burn rate. * * This function calculates the amount of tokens that should be burned from a given transaction * amount, based on the current burn rate. The burn rate is applied unless the sender's address * is whitelisted, in which case no tokens are burned. * * The function performs the following operations: * - It checks if the sender (`_from`) is whitelisted using the `mproRoleManager.isWhitelisted` * function. If the sender is whitelisted, the function returns 0, indicating no burn is applied. * - If the sender is not whitelisted, the function calculates the burn amount by applying the * burn rate to the transaction amount (`_amount`). The burn rate is represented as a percentage * scaled by a factor of 10000 (e.g., a burn rate of 10% is represented as 1000). The calculated * burn amount is then returned. * * This mechanism allows for a dynamic burn policy where certain addresses can be exempted from * burning, potentially for promotional or operational purposes. * * @param _from The address from which the tokens are being transferred. * @param _amount The amount of tokens being transferred, from which the burn amount will be calculated. * @return The calculated amount of tokens to be burned. */ function getBurnAmount( address _from, uint256 _amount ) external view returns (uint256) { // If the sender is whitelisted, no burn fee is applied if (isWhitelisted(_from)) { return 0; } return _amount.mul(burnRate).div(10000); } /** * @dev Sets the burn rate for the contract. * * This external function allows an account with the OWNER_ROLE to set the burn rate, * which is the percentage of the tokens that will be burned during certain operations. * The burn rate is expressed as a percentage with a precision of up to three decimal places. * For example, a burn rate of 1000 represents a 10% burn rate (1000 / 100 = 10%). * * A constraint is enforced to ensure that the burn rate does not exceed 10% (represented as 1000 * in the contract). This safeguard prevents setting an excessively high burn rate that could * adversely impact the token economy or operations of the contract. * * It's critical to input the correct value for the burn rate as it directly affects the token * dynamics. Only authorized accounts with the OWNER_ROLE can perform this operation, ensuring * that the burn rate is controlled and updated responsibly. * * @param _burnRate The new burn rate to be set, scaled by a factor of 100. For example, to set a * burn rate of 1%, `_burnFee` should be 10. */ function setBurnRate(uint256 _burnRate) external onlyOwner { require( _burnRate <= 1000, "MPROMasterDistributor: Burn rate cannot be greater than or equal to 10%" ); burnRate = _burnRate; emit SetBurnRate(_burnRate); } /** * @dev Assigns the DISTRIBUTIONS_ADMINISTRATOR_ROLE_MANAGER role to a specified address. This function * allows the contract owner to delegate the management of distribution time administrators to a specific * account. This is crucial for decentralized management and control over the distribution process. * * The function includes checks to ensure: * 1. The role has not been burned (permanently deactivated). * 2. The role has not already been granted to another account. * * If the role is available and active, the function grants the DISTRIBUTIONS_ADMINISTRATOR_ROLE_MANAGER role * to the specified address, marks the role as assigned in the `assignedRoles` mapping, and emits a * `SetDistributorTimeAdministratorRoleManager` event with the address of the new role manager. * * @param _roleManagerAddress The address to be assigned the DISTRIBUTIONS_ADMINISTRATOR_ROLE_MANAGER role. */ function setDistributorTimeAdministratorRoleManager( address _roleManagerAddress ) external onlyOwner notBurned(DISTRIBUTIONS_ADMINISTRATOR_ROLE_MANAGER) notGranted(DISTRIBUTIONS_ADMINISTRATOR_ROLE_MANAGER) { _grantRole( DISTRIBUTIONS_ADMINISTRATOR_ROLE_MANAGER, _roleManagerAddress ); assignedRoles[DISTRIBUTIONS_ADMINISTRATOR_ROLE_MANAGER] = true; emit SetDistributorTimeAdministratorRoleManager(_roleManagerAddress); } /** * @dev Assigns the DISTRIBUTIONS_ADMINISTRATOR_ROLE to a specified address. This function allows an account * with the DISTRIBUTIONS_ADMINISTRATOR_ROLE_MANAGER role to delegate the responsibilities of distribution * time administration to a specific account. This role is crucial for managing the distribution schedule * and ensuring the proper administration of the distribution process. * * The function includes checks to ensure: * 1. The caller has the DISTRIBUTIONS_ADMINISTRATOR_ROLE_MANAGER role, allowing them to manage this role. * 2. The DISTRIBUTIONS_ADMINISTRATOR_ROLE has not been burned (permanently deactivated). * 3. The DISTRIBUTIONS_ADMINISTRATOR_ROLE has not already been granted to another account. * * If the role is available and active, the function grants the DISTRIBUTIONS_ADMINISTRATOR_ROLE to the * specified address, marks the role as assigned in the `assignedRoles` mapping, and emits a * `SetDistributorTimeAdministratorRole` event with the address of the new role administrator. * * @param _roleManagerAddress The address to be assigned the DISTRIBUTIONS_ADMINISTRATOR_ROLE. */ function setDistributorTimeAdministratorRole( address _roleManagerAddress ) external onlyRole(DISTRIBUTIONS_ADMINISTRATOR_ROLE_MANAGER) notBurned(DISTRIBUTIONS_ADMINISTRATOR_ROLE) notGranted(DISTRIBUTIONS_ADMINISTRATOR_ROLE) { _grantRole(DISTRIBUTIONS_ADMINISTRATOR_ROLE, _roleManagerAddress); assignedRoles[DISTRIBUTIONS_ADMINISTRATOR_ROLE] = true; emit SetDistributorTimeAdministratorRole(_roleManagerAddress); } /** * @dev Public function to grant a specific role to an account. * * This function allows the contract owner to grant a specific role to the `_account` address. Roles * are used to define permissions and responsibilities within the contract, and granting a role confers * those associated privileges to the specified account. * * The function takes two parameters: * - `_role`: The bytes32 identifier of the role to be granted. * - `_account`: The address to which the role is to be granted. * * As a safeguard, the function enforces several preconditions before granting the role: * - Ensures that the `_account` address is not blocklisted, maintaining the security and integrity * of the contract by preventing potentially malicious entities from gaining privileged access. * - Checks that the `_account` address is not the zero address (`address(0)`), avoiding unintentional * role assignments to an address that may have special significance or represent "no address". * - Verifies that the role has not already been burned, ensuring that only active, valid roles are * assignable. * - Confirms that the role has not already been granted, upholding the principle of unique role assignments. * * This function can only be called by the contract owner, ensuring that role management is kept under * tight control and preventing unauthorized role assignments. * * @param _role The bytes32 identifier of the role to be granted. * @param _account The address to which the role is to be granted. * * Requirements: * - The contract caller must be the contract owner. * - The `_account` must not be blocklisted or the zero address. * - The `_role` must not be burned or already granted. */ function grantRole( bytes32 _role, address _account ) public virtual override onlyOwner notBlocklisted(_account) notZeroAddress(_account) notBurned(_role) notGranted(_role) { assignedRoles[_role] = true; _grantRole(_role, _account); } /** * @dev Public function to revoke a specific role from an account. * * This function allows the contract owner to remove a previously granted role from the `_account` address. * Roles are crucial for defining permissions and responsibilities within the contract, and revoking a role * removes those associated privileges from the specified account. * * The function takes two parameters: * - `_role`: The bytes32 identifier of the role to be revoked. * - `_account`: The address from which the role is to be removed. * * Before revoking the role, the function performs the following checks: * - Verifies that the `_account` address is not the zero address (`address(0)`) to prevent accidental * modifications of the zero address, which may have special significance. * - Ensures that the `_account` currently has the role to be revoked, providing a safeguard against * unnecessary or mistaken revocations. * * Access to this function is restricted to addresses with the `OWNER_ROLE`, ensuring that only contract * owners or administrators can revoke roles. Upon successful revocation of the role, the function updates * the `assignedRoles` mapping and calls the internal `_revokeRole` function. * * @param _role The bytes32 identifier of the role to be revoked. * @param _account The address from which the role is to be removed. * * Requirements: * - The `_account` address must not be the zero address (`address(0)`). * - The `_account` must currently have the role that is being revoked. */ function revokeRole( bytes32 _role, address _account ) public override onlyOwner notZeroAddress(_account) { require( hasRole(_role, _account), "MPROMasterDistributor: Account does not have role" ); assignedRoles[_role] = false; _revokeRole(_role, _account); } /** * @dev Public function for an account to renounce a specific role it possesses. * * This function allows an account to voluntarily renounce a role it holds, effectively removing the * associated permissions and responsibilities. It's a self-initiated action, meaning an account can * only renounce roles that it possesses for itself, enhancing the security by preventing external * entities from forcibly removing roles. * * The function takes two parameters: * - `_role`: The bytes32 identifier of the role to be renounced. * - `_account`: The address of the account renouncing the role. To ensure security and prevent * unintended renunciations, the function checks that `_account` is the same as `_msgSender()`. * * Before allowing the role to be renounced, the function performs the following check: * - Verifies that the `_account` address is not the zero address (`address(0)`) to prevent * accidental modifications of the zero address, which may have special significance. * * Upon successfully renouncing the role, the function updates the `assignedRoles` mapping and * calls the internal `_revokeRole` function to formally remove the role. * * @param _role The bytes32 identifier of the role to be renounced. * @param _account The address of the account renouncing the role. * * Requirements: * - The `_account` address must not be the zero address (`address(0)`). * - The `_account` must be the same as `_msgSender()`, ensuring that accounts can only renounce * roles for themselves. */ function renounceRole( bytes32 _role, address _account ) public override notZeroAddress(_account) { require( _account == _msgSender(), "AccessControl: can only renounce roles for self" ); require( hasRole(_role, _account), "MPROMasterDistributor: Account does not have role" ); assignedRoles[_role] = false; _revokeRole(_role, _account); } /** * @dev External function to blocklist or unblocklist an account. * * This function allows an address with the `LISTER_ROLE` to either blocklist or remove an account * from the contract's blocklist. Blocklisting an account may restrict it from performing certain * operations or participating in specific aspects of the contract, as defined by the contract's * logic. * * The function takes two parameters: * - `_account`: The address to be either blocklisted or unblocklisted. * - `_blocklist`: A boolean indicating whether to blocklist (`true`) or unblocklist (`false`) * the account. * * Before modifying the blocklist status, the function checks if the specified `_account` address * holds any other roles within the contract (owner, lister, pauser, distributor). If the account * has any of these roles, the function reverts to prevent the blocklisting of accounts with * roles. * * Access to this function is restricted to addresses with the `LISTER_ROLE`, ensuring that only * authorized entities can modify the blocklist. * * @param _account The address to be blocklisted or unblocklisted. * @param _blocklist A boolean indicating whether to blocklist or unblocklist the account. * * Requirements: * - The `_account` address must not be the zero address (`address(0)`). * This prevents accidentally modifying the zero address, which may have special significance. * - The `_account` address must not have any other roles (owner, lister, pauser, distributor). * Accounts with these roles cannot be blocklisted. */ function blocklist( address _account, bool _blocklist ) external onlyRole(LISTER_ROLE) notZeroAddress(_account) { if ( this.owner() == _account || isLister(_account) || isDistributor(_account) ) { revert( "MPROMasterDistributor: Account has a role and cannot be blocklisted" ); } blocklisted[_account] = _blocklist; } /** * @dev External function to whitelist or unwhitelist an account. * * This function allows an address with the `LISTER_ROLE` to either whitelist or remove an account * from the contract's whitelist. Whitelisting typically grants certain privileges or exemptions * to the whitelisted account, while removing an account from the whitelist revokes these * privileges. * * The function takes two parameters: * - `_account`: The address to be either whitelisted or removed from the whitelist. * - `_whitelist`: A boolean indicating whether to whitelist (`true`) or unwhitelist (`false`) * the account. * * The function sets the whitelisting status of the specified account by updating the `whitelisted` * mapping accordingly. * * Access to this function is restricted to addresses with the `LISTER_ROLE`, ensuring that only * authorized entities can modify the whitelist. * * @param _account The address to be whitelisted or unwhitelisted. * @param _whitelist A boolean indicating whether to whitelist or unwhitelist the account. * * Requirements: * - The `_account` address must not be the zero address (`address(0)`). * This prevents accidentally modifying the zero address, which may have special significance. */ function whitelist( address _account, bool _whitelist ) external onlyRole(LISTER_ROLE) notZeroAddress(_account) { whitelisted[_account] = _whitelist; } /** * @dev Public view function to check if an account has the LISTER_ROLE. * * This function provides a convenient way to verify if a specific account has been granted the LISTER_ROLE * within the contract. The LISTER_ROLE is typically associated with permissions to list items or manage * lists within the contract's ecosystem. * * The function takes a single parameter: * - `_account`: The address of the account to check for the LISTER_ROLE. * * It returns a boolean value indicating whether the specified account has the LISTER_ROLE. This can be * particularly useful for front-end interfaces or other contract interactions that require a quick check * of an account's roles or permissions. * * @param _account The address of the account to check for the LISTER_ROLE. * @return A boolean value indicating whether the specified account has the LISTER_ROLE. */ function isLister(address _account) public view returns (bool) { return hasRole(LISTER_ROLE, _account); } /** * @dev Public view function to check if an address has the MPROMasterDistributor role. * * This function provides a straightforward method to verify if a specific address has been granted the * MPROMasterDistributor role within the contract. The MPROMasterDistributor role is typically associated * with permissions to manage and execute token distributions, making it a critical role for the * operational aspects of the contract. * * The function takes a single parameter: * - `_address`: The address of the account to check for the MPROMasterDistributor role. * * It returns a boolean value indicating whether the specified address has the MPROMasterDistributor role. * This is particularly useful for confirming role assignments and managing access to distribution-related * functions or sections of a dApp interface. * * @param _address The address of the account to check for the MPROMasterDistributor role. * @return A boolean value indicating whether the specified address has the MPROMasterDistributor role. */ function isDistributor(address _address) public view returns (bool) { return hasRole(MPRO_MASTER_DISTRIBUTOR_ROLE, _address); } /** * @dev Public view function to check if an account is blocklisted. * * This function allows anyone to determine if a specific account is included in the contract's * blocklist. An account that is blocklisted may be restricted from performing certain operations * or participating in specific aspects of the contract, as defined by the contract's logic. * * The function checks the `blocklisted` mapping to see if the provided `_account` address is * marked as blocklisted, returning a boolean value indicating the blocklist status. * * Being a `view` function, it only reads the blocklist status from the contract's state and * does not modify the contract. This function is typically used in access control mechanisms * where actions are conditional based on whether an account is blocklisted. * * @param _account The address to be checked for blocklist status. * @return `true` if the account is blocklisted, `false` otherwise. */ function isBlocklisted(address _account) public view returns (bool) { return blocklisted[_account]; } /** * @dev External view function to check if an account is whitelisted. * * This function is accessible externally and is used to determine if a specific account is * included in the whitelist of the contract. Whitelisted accounts often have certain privileges * or are exempt from various restrictions that apply to other users. * * The function's logic is as follows: * - If the provided `_account` address is the zero address (`address(0)`), the function * returns `true`. This implies a default allowance or special treatment for the zero address * in certain contexts. * - For any other address, it checks the `whitelisted` mapping to see if the address is * marked as whitelisted, returning a boolean value that indicates the status. * * Being a `view` function, it does not modify the state of the contract but simply reads and * returns the whitelisting status. It is typically used in access control checks, where * different actions or permissions are granted based on the user's whitelist status. * * @param _account The address to be checked for its whitelisted status. * @return `true` if the account is whitelisted, `false` otherwise. */ function isWhitelisted(address _account) private view returns (bool) { if (_account == address(0)) { return true; } return whitelisted[_account]; } /** * @dev External view function to check if minting is allowed for a given address. * * This function checks whether the provided `_minter` address is authorized to mint new tokens. * In the current implementation, minting is restricted to the contract itself, signifying that * minting operations are controlled internally and not open to external entities directly. * * The function takes a single parameter: * - `_minter`: The address to be checked for minting permissions. * * It returns true if the `_minter` address is the same as the address of this contract, * indicating that minting is allowed. Otherwise, it reverts the transaction with the message * "MPROMasterDistributor: Distributor only", enforcing the rule that only the contract itself can initiate minting operations. * * @param _minter The address to be checked for minting permissions. * @return A boolean value indicating whether minting is allowed for the specified `_minter` address. */ function mintAllowed(address _minter) external view returns (bool) { require( _minter == address(this), "MPROMasterDistributor: Distributor only" ); return true; } /** * @dev Public view function to check if a token transfer is allowed. * * This function is used to enforce restrictions on token transfers based on blocklist criteria. * It checks whether any of the involved parties in a token transfer (the sender, receiver, and * the caller of the function) are on a blocklist. If any of these addresses are blocklisted, the * function reverts the transaction, preventing the transfer. * * Being a `view` function, it does not modify the state of the blockchain but reads from it. * This function can be integrated into the token transfer process to add an additional layer of * security and compliance, ensuring that tokens cannot be transferred by or to blocklisted * addresses. * * @param _from The address attempting to send tokens. * @param _to The address intended to receive the tokens. * @param _msgSender The address initiating the transfer request. * * Requirements: * - None of the involved addresses (_from, _to, and _msgSender) can be on the blocklist. * If any are blocklisted, the function reverts with an error message. */ function transferAllowed( address _from, address _to, address _msgSender ) external view returns (bool) { require( !isBlocklisted(_from) && !isBlocklisted(_to) && !isBlocklisted(_msgSender), "MPROMasterDistributor: Action on blocklisted account" ); return true; } /** * @dev Public view function to check if token approval is allowed. * * This function is used to enforce restrictions on token approvals based on blocklist criteria. * It checks whether the spender or the caller of the function (message sender) are on a * blocklist. If either of these addresses are blocklisted, the function reverts the transaction, * preventing the approval operation. * * This check is crucial in scenarios where blocklisted addresses should not be permitted to * interact with the token, including being approved to spend tokens on behalf of others. By * incorporating this function into the approval process, the contract adds an additional layer * of security and regulatory compliance. * * Being a `view` function, `approveAllowed` does not alter the state of the blockchain but * reads from it to ensure compliance with the blocklist rules before any approval is granted. * * @param _spender The address being granted permission to spend tokens. * @param _msgSender The address initiating the approval request. * * Requirements: * - Neither the spender (_spender) nor the initiator of the approval (_msgSender) can be * on the blocklist. If any of them are blocklisted, the function reverts with an error message. */ function approveAllowed( address _spender, address _msgSender ) external view returns (bool) { require( !isBlocklisted(_spender) && !isBlocklisted(_msgSender), "MPROMasterDistributor: Action on blocklisted account" ); return true; } /** * @dev External view function to retrieve the list of distribution reductions. * * This function provides access to the array of `distributionReductions`, which contains * records of all the reductions applied to the token distribution over time. Each record in * the array is a `DistributionReduction` struct, detailing the timestamp when the reduction * takes effect and the new daily distribution amount after the reduction. * * The function does not take any parameters and returns the entire array of * `distributionReductions`. This can be particularly useful for front-end interfaces or * other contract interactions that require visibility into the history and schedule of * distribution reductions. * * @return An array of `DistributionReduction` structs, representing the history of distribution reductions. */ function getDistributionReductions() external view returns (DistributionReduction[] memory) { return distributionReductions; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ```solidity * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(account), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer(address from, address to, uint256 amount) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated 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) (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.4.22 <0.9.0; library console { address constant CONSOLE_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; function _sendLogPayloadImplementation(bytes memory payload) internal view { address consoleAddress = CONSOLE_ADDRESS; /// @solidity memory-safe-assembly assembly { pop( staticcall( gas(), consoleAddress, add(payload, 32), mload(payload), 0, 0 ) ) } } function _castToPure( function(bytes memory) internal view fnIn ) internal pure returns (function(bytes memory) pure fnOut) { assembly { fnOut := fnIn } } function _sendLogPayload(bytes memory payload) internal pure { _castToPure(_sendLogPayloadImplementation)(payload); } function log() internal pure { _sendLogPayload(abi.encodeWithSignature("log()")); } function logInt(int256 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); } function logUint(uint256 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); } function logString(string memory p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function logBool(bool p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function logAddress(address p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function logBytes(bytes memory p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); } function logBytes1(bytes1 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); } function logBytes2(bytes2 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); } function logBytes3(bytes3 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); } function logBytes4(bytes4 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); } function logBytes5(bytes5 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); } function logBytes6(bytes6 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); } function logBytes7(bytes7 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); } function logBytes8(bytes8 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); } function logBytes9(bytes9 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); } function logBytes10(bytes10 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); } function logBytes11(bytes11 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); } function logBytes12(bytes12 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); } function logBytes13(bytes13 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); } function logBytes14(bytes14 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); } function logBytes15(bytes15 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); } function logBytes16(bytes16 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); } function logBytes17(bytes17 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); } function logBytes18(bytes18 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); } function logBytes19(bytes19 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); } function logBytes20(bytes20 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); } function logBytes21(bytes21 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); } function logBytes22(bytes22 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); } function logBytes23(bytes23 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); } function logBytes24(bytes24 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); } function logBytes25(bytes25 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); } function logBytes26(bytes26 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); } function logBytes27(bytes27 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); } function logBytes28(bytes28 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); } function logBytes29(bytes29 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); } function logBytes30(bytes30 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); } function logBytes31(bytes31 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); } function logBytes32(bytes32 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); } function log(uint256 p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); } function log(string memory p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function log(bool p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function log(address p0) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function log(uint256 p0, uint256 p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1)); } function log(uint256 p0, string memory p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1)); } function log(uint256 p0, bool p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1)); } function log(uint256 p0, address p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1)); } function log(string memory p0, uint256 p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); } function log(string memory p0, string memory p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); } function log(string memory p0, bool p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); } function log(string memory p0, address p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); } function log(bool p0, uint256 p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1)); } function log(bool p0, string memory p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); } function log(bool p0, bool p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); } function log(bool p0, address p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); } function log(address p0, uint256 p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1)); } function log(address p0, string memory p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); } function log(address p0, bool p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); } function log(address p0, address p1) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); } function log(uint256 p0, uint256 p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2)); } function log(uint256 p0, string memory p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2)); } function log(uint256 p0, string memory p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2)); } function log(uint256 p0, string memory p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2)); } function log(uint256 p0, string memory p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2)); } function log(uint256 p0, bool p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2)); } function log(uint256 p0, bool p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2)); } function log(uint256 p0, bool p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2)); } function log(uint256 p0, bool p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2)); } function log(uint256 p0, address p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2)); } function log(uint256 p0, address p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2)); } function log(uint256 p0, address p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2)); } function log(uint256 p0, address p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2)); } function log(string memory p0, uint256 p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2)); } function log(string memory p0, uint256 p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2)); } function log(string memory p0, uint256 p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2)); } function log(string memory p0, uint256 p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2)); } function log(string memory p0, string memory p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2)); } function log(string memory p0, string memory p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); } function log(string memory p0, string memory p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); } function log(string memory p0, string memory p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); } function log(string memory p0, bool p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2)); } function log(string memory p0, bool p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); } function log(string memory p0, bool p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); } function log(string memory p0, bool p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); } function log(string memory p0, address p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2)); } function log(string memory p0, address p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); } function log(string memory p0, address p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); } function log(string memory p0, address p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); } function log(bool p0, uint256 p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2)); } function log(bool p0, uint256 p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2)); } function log(bool p0, uint256 p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2)); } function log(bool p0, uint256 p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2)); } function log(bool p0, string memory p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2)); } function log(bool p0, string memory p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); } function log(bool p0, string memory p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); } function log(bool p0, string memory p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); } function log(bool p0, bool p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2)); } function log(bool p0, bool p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); } function log(bool p0, bool p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); } function log(bool p0, bool p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); } function log(bool p0, address p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2)); } function log(bool p0, address p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); } function log(bool p0, address p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); } function log(bool p0, address p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); } function log(address p0, uint256 p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2)); } function log(address p0, uint256 p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2)); } function log(address p0, uint256 p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2)); } function log(address p0, uint256 p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2)); } function log(address p0, string memory p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2)); } function log(address p0, string memory p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); } function log(address p0, string memory p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); } function log(address p0, string memory p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); } function log(address p0, bool p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2)); } function log(address p0, bool p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); } function log(address p0, bool p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); } function log(address p0, bool p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); } function log(address p0, address p1, uint256 p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2)); } function log(address p0, address p1, string memory p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); } function log(address p0, address p1, bool p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); } function log(address p0, address p1, address p2) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); } function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, uint256 p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, string memory p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, bool p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3)); } function log(uint256 p0, address p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint256 p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3)); } function log(bool p0, uint256 p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3)); } function log(address p0, uint256 p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, uint256 p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, uint256 p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, string memory p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, bool p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, address p3) internal pure { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_redutionTimestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_reductionAmount","type":"uint256"}],"name":"AddDistributionReduction","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Distributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_burnRate","type":"uint256"}],"name":"SetBurnRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_startTime","type":"uint256"}],"name":"SetDistribiutionStartTime","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_roleManagerAddress","type":"address"}],"name":"SetDistributorTimeAdministratorRole","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_roleManagerAddress","type":"address"}],"name":"SetDistributorTimeAdministratorRoleManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_mproTokenAddress","type":"address"}],"name":"SetMPRO","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DISTRIBUTIONS_ADMINISTRATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DISTRIBUTIONS_ADMINISTRATOR_ROLE_MANAGER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LISTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MPRO_MASTER_DISTRIBUTOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_redutionTimestamp","type":"uint256"},{"internalType":"uint256","name":"_reductionAmount","type":"uint256"}],"name":"addDistributionReduction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"address","name":"_msgSender","type":"address"}],"name":"approveAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bool","name":"_blocklist","type":"bool"}],"name":"blocklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burnRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_to","type":"address[]"},{"internalType":"uint256[]","name":"_amount","type":"uint256[]"}],"name":"distributeBulk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distributionStartTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllTokenDistribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"getBurnAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDistributionReductions","outputs":[{"components":[{"internalType":"uint256","name":"reductionTimestamp","type":"uint256"},{"internalType":"uint256","name":"daylyDistribution","type":"uint256"}],"internalType":"struct MPROMasterDistributor.DistributionReduction[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_role","type":"bytes32"},{"internalType":"address","name":"_account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialDaylyDistribution","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isBlocklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isDistributor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isLister","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"mintAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_role","type":"bytes32"},{"internalType":"address","name":"_account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_role","type":"bytes32"},{"internalType":"address","name":"_account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_burnRate","type":"uint256"}],"name":"setBurnRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startTime","type":"uint256"}],"name":"setDistributionStartTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_roleManagerAddress","type":"address"}],"name":"setDistributorTimeAdministratorRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_roleManagerAddress","type":"address"}],"name":"setDistributorTimeAdministratorRoleManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mproTokenAddress","type":"address"}],"name":"setMPRO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"address","name":"_msgSender","type":"address"}],"name":"transferAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bool","name":"_whitelist","type":"bool"}],"name":"whitelist","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a06040526103e86009553480156200001757600080fd5b506040516200279b3803806200279b8339810160408190526200003a91620000cd565b62000045336200007b565b620000544262127500620000ff565b600655620000664262278d00620000ff565b60805262000074816200007b565b5062000127565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060208284031215620000e057600080fd5b81516001600160a01b0381168114620000f857600080fd5b9392505050565b808201808211156200012157634e487b7160e01b600052601160045260246000fd5b92915050565b6080516126586200014360003960006113f101526126586000f3fe608060405234801561001057600080fd5b506004361061021c5760003560e01c806393fc9e5f11610125578063bf90fbc6116100ad578063eba1c66b1161007c578063eba1c66b1461047e578063f2fde38b14610491578063f59c3708146104a4578063fb932108146104b7578063fc0e8c1b146104ca57600080fd5b8063bf90fbc614610430578063d2b7077914610443578063d547741f14610456578063deb26b941461046957600080fd5b8063a3df582a116100f4578063a3df582a146103e7578063ad33628f146103f0578063b7c4a6bf14610401578063b962cbaf14610414578063bed998501461042757600080fd5b806393fc9e5f146103a657806395cde8b4146103b95780639d8ff965146103cc578063a217fddf146103df57600080fd5b8063517f25a2116101a85780638f075145116101775780638f075145146103435780638f0c86fa14610356578063909fe67b1461036957806391d148541461037e57806393bcc9231461039157600080fd5b8063517f25a2146102f8578063715018a61461030d5780638da5cb5b146103155780638e204c431461033057600080fd5b80632117086f116101ef5780632117086f14610289578063248a9ca31461029c5780632f2ff15d146102bf57806336568abe146102d257806340c75ea9146102e557600080fd5b806301ffc9a714610221578063079ddd6d146102495780631765b6911461025e578063189d165e14610274575b600080fd5b61023461022f366004611f09565b6104dd565b60405190151581526020015b60405180910390f35b610251610514565b6040516102409190611f33565b610266610587565b604051908152602001610240565b610287610282366004611f82565b610819565b005b610287610297366004611f9b565b6108ea565b6102666102aa366004611f82565b60009081526020819052604090206001015490565b6102876102cd366004611fd2565b610c8b565b6102876102e0366004611fd2565b610d7a565b6102876102f33660046120dc565b610ea6565b6102666000805160206125e383398151915281565b610287610f7c565b6001546040516001600160a01b039091168152602001610240565b61023461033e36600461219e565b610f90565b61028761035136600461219e565b610fae565b61023461036436600461219e565b6110e4565b61026660008051602061260383398151915281565b61023461038c366004611fd2565b6110fa565b6102666000805160206125a383398151915281565b6102346103b43660046121bb565b611123565b6102346103c736600461219e565b611179565b6102876103da36600461219e565b6111d9565b610266600081565b61026660065481565b6102666934f086f3b33b6840000081565b61026661040f366004612206565b6112a1565b610287610422366004611f82565b6112e1565b61026660095481565b61028761043e36600461219e565b6114ce565b610234610451366004612232565b611615565b610287610464366004611fd2565b611658565b61026660008051602061258383398151915281565b61028761048c366004612260565b611687565b61028761049f36600461219e565b611806565b6102876104b2366004612260565b61187f565b6102876104c5366004612206565b6118eb565b6102346104d836600461219e565b611ad2565b60006001600160e01b03198216637965db0b60e01b148061050e57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606008805480602002602001604051908101604052809291908181526020016000905b8282101561057e57838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190610538565b50505050905090565b60006006544210156105995750600090565b60006008805480602002602001604051908101604052809291908181526020016000905b82821015610603578382906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050815260200190600101906105bd565b50505050905060006006544261061991906122a9565b9050600061062a62015180836122bc565b835190915060009042905b80156106df576000866106496001846122a9565b81518110610659576106596122de565b60200260200101519050806000015142106106cc578051600090620151809061068290866122a9565b61068c91906122bc565b905081602001518161069e91906122f4565b82602001516106ad919061230b565b6106b7908661230b565b825190955093506106c881876122a9565b9550505b50806106d78161231e565b915050610635565b506106f46934f086f3b33b68400000846122f4565b610708906934f086f3b33b6840000061230b565b610712908361230b565b9150600260009054906101000a90046001600160a01b03166001600160a01b03166323548b8b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610767573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078b9190612335565b821015610798578161080f565b600260009054906101000a90046001600160a01b03166001600160a01b03166323548b8b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080f9190612335565b9550505050505090565b610821611aec565b6103e88111156108ae5760405162461bcd60e51b815260206004820152604760248201527f4d50524f4d61737465724469737472696275746f723a204275726e207261746560448201527f2063616e6e6f742062652067726561746572207468616e206f7220657175616c60648201526620746f2031302560c81b608482015260a4015b60405180910390fd5b60098190556040518181527f9184e9ae9554b2f814a8bdda1712d37b4b6ae7aac79868386ac664e57ce1dcf3906020015b60405180910390a150565b6000805160206125e383398151915261090281611b46565b8282610921604051806040016040528060008152602001600081525090565b6008541561097d5760088054610939906001906122a9565b81548110610949576109496122de565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050905061099e565b506040805180820190915260065481526934f086f3b33b6840000060208201525b80516109ad9062f1428061230b565b831015610a5b5760405162461bcd60e51b815260206004820152606a60248201527f4d50524f4d61737465724469737472696275746f723a204e657720726564757460448201527f696f6e2073746172742074696d652063616e6e6f74206265206c6f776572207460648201527f68616e203138332064617973206166746572206c617374207265647574696f6e60848201526902074696d657374616d760b41b60a482015260c4016108a5565b6020810151610a6b906002611b50565b821015610b145760405162461bcd60e51b8152602060048201526064602482018190527f4d50524f4d61737465724469737472696275746f723a204e657720726564756360448301527f74696f6e20616d6f756e742063616e6e6f742062652067726561746572207468908201527f616e2068616c66206f6620746865206c61737420726564756374696f6e20616d6084820152631bdd5b9d60e21b60a482015260c4016108a5565b6020810151610b24906002611b5c565b821115610bd45760405162461bcd60e51b815260206004820152606c60248201527f4d50524f4d61737465724469737472696275746f723a204e657720726564756360448201527f74696f6e20616d6f756e742063616e6e6f74206265206772656174657220746860648201527f616e20746865206c61737420726564756374696f6e20616d6f756e74206d756c60848201526b3a34b83634b2b210313c901960a11b60a482015260c4016108a5565b60408051808201825287815260208082018881526008805460018101825560009190915292517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3600290940293840155517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee49092019190915581518881529081018790527f753d15e0c64e5ba659389066f8d03d486700c959348e556618057a587d066a79910160405180910390a1505050505050565b610c93611aec565b6001600160a01b038116600090815260046020526040902054819060ff1615610cce5760405162461bcd60e51b81526004016108a59061234e565b816001600160a01b038116610cf55760405162461bcd60e51b81526004016108a5906123a2565b83610d018160006110fa565b15610d1e5760405162461bcd60e51b81526004016108a5906123ef565b600085815260036020526040902054859060ff1615610d4f5760405162461bcd60e51b81526004016108a59061243c565b6000868152600360205260409020805460ff19166001179055610d728686611b68565b505050505050565b806001600160a01b038116610da15760405162461bcd60e51b81526004016108a5906123a2565b6001600160a01b0382163314610e115760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108a5565b610e1b83836110fa565b610e815760405162461bcd60e51b815260206004820152603160248201527f4d50524f4d61737465724469737472696275746f723a204163636f756e7420646044820152706f6573206e6f74206861766520726f6c6560781b60648201526084016108a5565b6000838152600360205260409020805460ff19169055610ea18383611bed565b505050565b600080516020612603833981519152610ebe81611b46565b8151835114610f265760405162461bcd60e51b815260206004820152602e60248201527f746f20616e6420616d6f756e7420617272617973206d7573742068617665207460448201526d0d0ca40e6c2daca40d8cadccee8d60931b60648201526084016108a5565b60005b8351811015610f7657610f6e848281518110610f4757610f476122de565b6020026020010151848381518110610f6157610f616122de565b60200260200101516118eb565b600101610f29565b50505050565b610f84611aec565b610f8e6000611c52565b565b6001600160a01b031660009081526004602052604090205460ff1690565b610fb6611aec565b6000805160206125a3833981519152610fd08160006110fa565b15610fed5760405162461bcd60e51b81526004016108a5906123ef565b6000805160206125a3833981519152600081905260036020527ff9830402bbafcd668269671b0f591a9864fddce5aeead4a4a535deea5f7d4eea5460ff16156110485760405162461bcd60e51b81526004016108a59061243c565b6110606000805160206125a383398151915284611b68565b6000805160206125a3833981519152600052600360209081527ff9830402bbafcd668269671b0f591a9864fddce5aeead4a4a535deea5f7d4eea805460ff191660011790556040516001600160a01b03851681527f1653e4398425e1efcb20d294dbbf89446912817a166b95f7629558baef459ecd910160405180910390a1505050565b600061050e600080516020612603833981519152835b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b600061112e84610f90565b158015611141575061113f83610f90565b155b8015611153575061115182610f90565b155b61116f5760405162461bcd60e51b81526004016108a59061234e565b5060019392505050565b60006001600160a01b03821630146111d15760405162461bcd60e51b815260206004820152602760248201526000805160206125c38339815191526044820152666f72206f6e6c7960c81b60648201526084016108a5565b506001919050565b6111e1611aec565b6002546001600160a01b0316156112535760405162461bcd60e51b815260206004820152603060248201527f4d50524f4d61737465724469737472696275746f723a204d50524f20746f6b6560448201526f1b881a5cc8185b1c9958591e481cd95d60821b60648201526084016108a5565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f70e45101e604b9c510027b3c1c6910df59a2a8e79ac19f9c3f7c0b2e23a2bc30906020016108df565b60006112ac83611ca4565b156112b95750600061050e565b6112da6127106112d460095485611b5c90919063ffffffff16565b90611b50565b9392505050565b6112e9611aec565b600754156113735760405162461bcd60e51b815260206004820152605f60248201526000805160206125c383398151915260448201527f696f6e2073746172742074696d652063616e6e6f74206265206368616e67656460648201527f20616674657220646973747269627574696f6e20686173207374617274656400608482015260a4016108a5565b4281116113ef5760405162461bcd60e51b815260206004820152605060248201526000805160206125c383398151915260448201527f696f6e2073746172742074696d652063616e6e6f74206265206c6f776572207460648201526f68616e2063757272656e742074696d6560801b608482015260a4016108a5565b7f00000000000000000000000000000000000000000000000000000000000000008111156114995760405162461bcd60e51b815260206004820152605e60248201526000805160206125c383398151915260448201527f696f6e2073746172742074696d65206d757374206265206c657373207468616e60648201527f20646973747269627574696f6e537461727454696d65446561646c696e650000608482015260a4016108a5565b60068190556040518181527fc8e2be95c2a499f9692e142afc6b178470bd8e16d080e91497658c20e2824847906020016108df565b6000805160206125a38339815191526114e681611b46565b6000805160206125e38339815191526115008160006110fa565b1561151d5760405162461bcd60e51b81526004016108a5906123ef565b6000805160206125e3833981519152600081905260036020527feaea521b0fa1c79f9189cdc6d8d5f17d784b28b30b94868dd16f50216f20ffd25460ff16156115785760405162461bcd60e51b81526004016108a59061243c565b6115906000805160206125e383398151915285611b68565b6000805160206125e3833981519152600052600360209081527feaea521b0fa1c79f9189cdc6d8d5f17d784b28b30b94868dd16f50216f20ffd2805460ff191660011790556040516001600160a01b03861681527fd79838a02a85292deb7f2e9e20a140c1313678e1c21a2117d99df07532150a7b910160405180910390a150505050565b600061162083610f90565b158015611633575061163182610f90565b155b61164f5760405162461bcd60e51b81526004016108a59061234e565b50600192915050565b611660611aec565b806001600160a01b038116610e115760405162461bcd60e51b81526004016108a5906123a2565b60008051602061258383398151915261169f81611b46565b826001600160a01b0381166116c65760405162461bcd60e51b81526004016108a5906123a2565b836001600160a01b0316306001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117329190612499565b6001600160a01b0316148061174b575061174b84611ad2565b8061175a575061175a846110e4565b156117d95760405162461bcd60e51b815260206004820152604360248201527f4d50524f4d61737465724469737472696275746f723a204163636f756e74206860448201527f6173206120726f6c6520616e642063616e6e6f7420626520626c6f636b6c69736064820152621d195960ea1b608482015260a4016108a5565b50506001600160a01b03919091166000908152600460205260409020805460ff1916911515919091179055565b61180e611aec565b6001600160a01b0381166118735760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108a5565b61187c81611c52565b50565b60008051602061258383398151915261189781611b46565b826001600160a01b0381166118be5760405162461bcd60e51b81526004016108a5906123a2565b50506001600160a01b03919091166000908152600560205260409020805460ff1916911515919091179055565b60008051602061260383398151915261190381611b46565b600082116119535760405162461bcd60e51b815260206004820152601d60248201527f616d6f756e74206d7573742062652067726561746572207468616e203000000060448201526064016108a5565b6006544210156119b25760405162461bcd60e51b815260206004820152603660248201526000805160206125c38339815191526044820152751a5bdb881a5cc81b9bdd08195b98589b1959081e595d60521b60648201526084016108a5565b6119ba611cdb565b821115611a125760405162461bcd60e51b815260206004820152603260248201526000805160206125c38339815191526044820152711a5bdb881b1a5b5a5d08195e18d95959195960721b60648201526084016108a5565b6002546040516340c10f1960e01b81526001600160a01b03858116600483015260248201859052909116906340c10f1990604401600060405180830381600087803b158015611a6057600080fd5b505af1158015611a74573d6000803e3d6000fd5b505050508160076000828254611a8a919061230b565b90915550506040518281526001600160a01b038416907fb649c98f58055c520df0dcb5709eff2e931217ff2fb1e21376130d31bbb1c0af9060200160405180910390a2505050565b600061050e600080516020612583833981519152836110fa565b6001546001600160a01b03163314610f8e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108a5565b61187c8133611cf6565b60006112da82846122bc565b60006112da82846122f4565b611b7282826110fa565b611be9576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055611ba83390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b611bf782826110fa565b15611be9576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006001600160a01b038216611cbc57506001919050565b506001600160a01b031660009081526005602052604090205460ff1690565b6000611cf1600754611ceb610587565b90611d4f565b905090565b611d0082826110fa565b611be957611d0d81611d5b565b611d18836020611d6d565b604051602001611d299291906124da565b60408051601f198184030181529082905262461bcd60e51b82526108a59160040161254f565b60006112da82846122a9565b606061050e6001600160a01b03831660145b60606000611d7c8360026122f4565b611d8790600261230b565b67ffffffffffffffff811115611d9f57611d9f612002565b6040519080825280601f01601f191660200182016040528015611dc9576020820181803683370190505b509050600360fc1b81600081518110611de457611de46122de565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611e1357611e136122de565b60200101906001600160f81b031916908160001a9053506000611e378460026122f4565b611e4290600161230b565b90505b6001811115611eba576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110611e7657611e766122de565b1a60f81b828281518110611e8c57611e8c6122de565b60200101906001600160f81b031916908160001a90535060049490941c93611eb38161231e565b9050611e45565b5083156112da5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108a5565b600060208284031215611f1b57600080fd5b81356001600160e01b0319811681146112da57600080fd5b602080825282518282018190526000919060409081850190868401855b82811015611f7557815180518552860151868501529284019290850190600101611f50565b5091979650505050505050565b600060208284031215611f9457600080fd5b5035919050565b60008060408385031215611fae57600080fd5b50508035926020909101359150565b6001600160a01b038116811461187c57600080fd5b60008060408385031215611fe557600080fd5b823591506020830135611ff781611fbd565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561204157612041612002565b604052919050565b600067ffffffffffffffff82111561206357612063612002565b5060051b60200190565b600082601f83011261207e57600080fd5b8135602061209361208e83612049565b612018565b8083825260208201915060208460051b8701019350868411156120b557600080fd5b602086015b848110156120d157803583529183019183016120ba565b509695505050505050565b600080604083850312156120ef57600080fd5b823567ffffffffffffffff8082111561210757600080fd5b818501915085601f83011261211b57600080fd5b8135602061212b61208e83612049565b82815260059290921b8401810191818101908984111561214a57600080fd5b948201945b8386101561217157853561216281611fbd565b8252948201949082019061214f565b9650508601359250508082111561218757600080fd5b506121948582860161206d565b9150509250929050565b6000602082840312156121b057600080fd5b81356112da81611fbd565b6000806000606084860312156121d057600080fd5b83356121db81611fbd565b925060208401356121eb81611fbd565b915060408401356121fb81611fbd565b809150509250925092565b6000806040838503121561221957600080fd5b823561222481611fbd565b946020939093013593505050565b6000806040838503121561224557600080fd5b823561225081611fbd565b91506020830135611ff781611fbd565b6000806040838503121561227357600080fd5b823561227e81611fbd565b915060208301358015158114611ff757600080fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111561050e5761050e612293565b6000826122d957634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b808202811582820484141761050e5761050e612293565b8082018082111561050e5761050e612293565b60008161232d5761232d612293565b506000190190565b60006020828403121561234757600080fd5b5051919050565b60208082526034908201527f4d50524f4d61737465724469737472696275746f723a20416374696f6e206f6e60408201527308189b1bd8dadb1a5cdd1959081858d8dbdd5b9d60621b606082015260800190565b6020808252602d908201527f4d50524f4d61737465724469737472696275746f723a20416374696f6e206f6e60408201526c2061646472657373207a65726f60981b606082015260800190565b6020808252602d908201527f4d50524f4d61737465724469737472696275746f723a20526f6c65206973206160408201526c1b1c9958591e48189d5c9b9959609a1b606082015260800190565b6020808252603e908201527f4d50524f4d61737465724469737472696275746f723a20526f6c6520616c726560408201527f616479206772616e74656420746f20616e6f74686572206163636f756e740000606082015260800190565b6000602082840312156124ab57600080fd5b81516112da81611fbd565b60005b838110156124d15781810151838201526020016124b9565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516125128160178501602088016124b6565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516125438160288401602088016124b6565b01602801949350505050565b602081526000825180602084015261256e8160408501602087016124b6565b601f01601f1916919091016040019291505056fef94103142c1baabe9ac2b5d1487bf783de9e69cfeea9a72f5c9c94afd7877b8c6ee0f19c3526ca65945666b9437299b6a1b226cdffcd62f34d1cbc222cb026824d50524f4d61737465724469737472696275746f723a204469737472696275745afa424c0b6204848cb71c5aa5f8da1afaf45d645ada516ab6c53bb3ff616cffb19c0b5de53e6e8b2996523385ad2b2e358ef774bb7335734b02556c8b75f198a264697066735822122082500f0669a15f863c873b0eecfa357019769a54600554b0ee7657a776ff9fb764736f6c6343000816003300000000000000000000000003a1b656565e7c20aa4fadd4338f5fa73585a62b
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061021c5760003560e01c806393fc9e5f11610125578063bf90fbc6116100ad578063eba1c66b1161007c578063eba1c66b1461047e578063f2fde38b14610491578063f59c3708146104a4578063fb932108146104b7578063fc0e8c1b146104ca57600080fd5b8063bf90fbc614610430578063d2b7077914610443578063d547741f14610456578063deb26b941461046957600080fd5b8063a3df582a116100f4578063a3df582a146103e7578063ad33628f146103f0578063b7c4a6bf14610401578063b962cbaf14610414578063bed998501461042757600080fd5b806393fc9e5f146103a657806395cde8b4146103b95780639d8ff965146103cc578063a217fddf146103df57600080fd5b8063517f25a2116101a85780638f075145116101775780638f075145146103435780638f0c86fa14610356578063909fe67b1461036957806391d148541461037e57806393bcc9231461039157600080fd5b8063517f25a2146102f8578063715018a61461030d5780638da5cb5b146103155780638e204c431461033057600080fd5b80632117086f116101ef5780632117086f14610289578063248a9ca31461029c5780632f2ff15d146102bf57806336568abe146102d257806340c75ea9146102e557600080fd5b806301ffc9a714610221578063079ddd6d146102495780631765b6911461025e578063189d165e14610274575b600080fd5b61023461022f366004611f09565b6104dd565b60405190151581526020015b60405180910390f35b610251610514565b6040516102409190611f33565b610266610587565b604051908152602001610240565b610287610282366004611f82565b610819565b005b610287610297366004611f9b565b6108ea565b6102666102aa366004611f82565b60009081526020819052604090206001015490565b6102876102cd366004611fd2565b610c8b565b6102876102e0366004611fd2565b610d7a565b6102876102f33660046120dc565b610ea6565b6102666000805160206125e383398151915281565b610287610f7c565b6001546040516001600160a01b039091168152602001610240565b61023461033e36600461219e565b610f90565b61028761035136600461219e565b610fae565b61023461036436600461219e565b6110e4565b61026660008051602061260383398151915281565b61023461038c366004611fd2565b6110fa565b6102666000805160206125a383398151915281565b6102346103b43660046121bb565b611123565b6102346103c736600461219e565b611179565b6102876103da36600461219e565b6111d9565b610266600081565b61026660065481565b6102666934f086f3b33b6840000081565b61026661040f366004612206565b6112a1565b610287610422366004611f82565b6112e1565b61026660095481565b61028761043e36600461219e565b6114ce565b610234610451366004612232565b611615565b610287610464366004611fd2565b611658565b61026660008051602061258383398151915281565b61028761048c366004612260565b611687565b61028761049f36600461219e565b611806565b6102876104b2366004612260565b61187f565b6102876104c5366004612206565b6118eb565b6102346104d836600461219e565b611ad2565b60006001600160e01b03198216637965db0b60e01b148061050e57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606008805480602002602001604051908101604052809291908181526020016000905b8282101561057e57838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190610538565b50505050905090565b60006006544210156105995750600090565b60006008805480602002602001604051908101604052809291908181526020016000905b82821015610603578382906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050815260200190600101906105bd565b50505050905060006006544261061991906122a9565b9050600061062a62015180836122bc565b835190915060009042905b80156106df576000866106496001846122a9565b81518110610659576106596122de565b60200260200101519050806000015142106106cc578051600090620151809061068290866122a9565b61068c91906122bc565b905081602001518161069e91906122f4565b82602001516106ad919061230b565b6106b7908661230b565b825190955093506106c881876122a9565b9550505b50806106d78161231e565b915050610635565b506106f46934f086f3b33b68400000846122f4565b610708906934f086f3b33b6840000061230b565b610712908361230b565b9150600260009054906101000a90046001600160a01b03166001600160a01b03166323548b8b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610767573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078b9190612335565b821015610798578161080f565b600260009054906101000a90046001600160a01b03166001600160a01b03166323548b8b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080f9190612335565b9550505050505090565b610821611aec565b6103e88111156108ae5760405162461bcd60e51b815260206004820152604760248201527f4d50524f4d61737465724469737472696275746f723a204275726e207261746560448201527f2063616e6e6f742062652067726561746572207468616e206f7220657175616c60648201526620746f2031302560c81b608482015260a4015b60405180910390fd5b60098190556040518181527f9184e9ae9554b2f814a8bdda1712d37b4b6ae7aac79868386ac664e57ce1dcf3906020015b60405180910390a150565b6000805160206125e383398151915261090281611b46565b8282610921604051806040016040528060008152602001600081525090565b6008541561097d5760088054610939906001906122a9565b81548110610949576109496122de565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050905061099e565b506040805180820190915260065481526934f086f3b33b6840000060208201525b80516109ad9062f1428061230b565b831015610a5b5760405162461bcd60e51b815260206004820152606a60248201527f4d50524f4d61737465724469737472696275746f723a204e657720726564757460448201527f696f6e2073746172742074696d652063616e6e6f74206265206c6f776572207460648201527f68616e203138332064617973206166746572206c617374207265647574696f6e60848201526902074696d657374616d760b41b60a482015260c4016108a5565b6020810151610a6b906002611b50565b821015610b145760405162461bcd60e51b8152602060048201526064602482018190527f4d50524f4d61737465724469737472696275746f723a204e657720726564756360448301527f74696f6e20616d6f756e742063616e6e6f742062652067726561746572207468908201527f616e2068616c66206f6620746865206c61737420726564756374696f6e20616d6084820152631bdd5b9d60e21b60a482015260c4016108a5565b6020810151610b24906002611b5c565b821115610bd45760405162461bcd60e51b815260206004820152606c60248201527f4d50524f4d61737465724469737472696275746f723a204e657720726564756360448201527f74696f6e20616d6f756e742063616e6e6f74206265206772656174657220746860648201527f616e20746865206c61737420726564756374696f6e20616d6f756e74206d756c60848201526b3a34b83634b2b210313c901960a11b60a482015260c4016108a5565b60408051808201825287815260208082018881526008805460018101825560009190915292517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3600290940293840155517ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee49092019190915581518881529081018790527f753d15e0c64e5ba659389066f8d03d486700c959348e556618057a587d066a79910160405180910390a1505050505050565b610c93611aec565b6001600160a01b038116600090815260046020526040902054819060ff1615610cce5760405162461bcd60e51b81526004016108a59061234e565b816001600160a01b038116610cf55760405162461bcd60e51b81526004016108a5906123a2565b83610d018160006110fa565b15610d1e5760405162461bcd60e51b81526004016108a5906123ef565b600085815260036020526040902054859060ff1615610d4f5760405162461bcd60e51b81526004016108a59061243c565b6000868152600360205260409020805460ff19166001179055610d728686611b68565b505050505050565b806001600160a01b038116610da15760405162461bcd60e51b81526004016108a5906123a2565b6001600160a01b0382163314610e115760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108a5565b610e1b83836110fa565b610e815760405162461bcd60e51b815260206004820152603160248201527f4d50524f4d61737465724469737472696275746f723a204163636f756e7420646044820152706f6573206e6f74206861766520726f6c6560781b60648201526084016108a5565b6000838152600360205260409020805460ff19169055610ea18383611bed565b505050565b600080516020612603833981519152610ebe81611b46565b8151835114610f265760405162461bcd60e51b815260206004820152602e60248201527f746f20616e6420616d6f756e7420617272617973206d7573742068617665207460448201526d0d0ca40e6c2daca40d8cadccee8d60931b60648201526084016108a5565b60005b8351811015610f7657610f6e848281518110610f4757610f476122de565b6020026020010151848381518110610f6157610f616122de565b60200260200101516118eb565b600101610f29565b50505050565b610f84611aec565b610f8e6000611c52565b565b6001600160a01b031660009081526004602052604090205460ff1690565b610fb6611aec565b6000805160206125a3833981519152610fd08160006110fa565b15610fed5760405162461bcd60e51b81526004016108a5906123ef565b6000805160206125a3833981519152600081905260036020527ff9830402bbafcd668269671b0f591a9864fddce5aeead4a4a535deea5f7d4eea5460ff16156110485760405162461bcd60e51b81526004016108a59061243c565b6110606000805160206125a383398151915284611b68565b6000805160206125a3833981519152600052600360209081527ff9830402bbafcd668269671b0f591a9864fddce5aeead4a4a535deea5f7d4eea805460ff191660011790556040516001600160a01b03851681527f1653e4398425e1efcb20d294dbbf89446912817a166b95f7629558baef459ecd910160405180910390a1505050565b600061050e600080516020612603833981519152835b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b600061112e84610f90565b158015611141575061113f83610f90565b155b8015611153575061115182610f90565b155b61116f5760405162461bcd60e51b81526004016108a59061234e565b5060019392505050565b60006001600160a01b03821630146111d15760405162461bcd60e51b815260206004820152602760248201526000805160206125c38339815191526044820152666f72206f6e6c7960c81b60648201526084016108a5565b506001919050565b6111e1611aec565b6002546001600160a01b0316156112535760405162461bcd60e51b815260206004820152603060248201527f4d50524f4d61737465724469737472696275746f723a204d50524f20746f6b6560448201526f1b881a5cc8185b1c9958591e481cd95d60821b60648201526084016108a5565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527f70e45101e604b9c510027b3c1c6910df59a2a8e79ac19f9c3f7c0b2e23a2bc30906020016108df565b60006112ac83611ca4565b156112b95750600061050e565b6112da6127106112d460095485611b5c90919063ffffffff16565b90611b50565b9392505050565b6112e9611aec565b600754156113735760405162461bcd60e51b815260206004820152605f60248201526000805160206125c383398151915260448201527f696f6e2073746172742074696d652063616e6e6f74206265206368616e67656460648201527f20616674657220646973747269627574696f6e20686173207374617274656400608482015260a4016108a5565b4281116113ef5760405162461bcd60e51b815260206004820152605060248201526000805160206125c383398151915260448201527f696f6e2073746172742074696d652063616e6e6f74206265206c6f776572207460648201526f68616e2063757272656e742074696d6560801b608482015260a4016108a5565b7f000000000000000000000000000000000000000000000000000000006646f26b8111156114995760405162461bcd60e51b815260206004820152605e60248201526000805160206125c383398151915260448201527f696f6e2073746172742074696d65206d757374206265206c657373207468616e60648201527f20646973747269627574696f6e537461727454696d65446561646c696e650000608482015260a4016108a5565b60068190556040518181527fc8e2be95c2a499f9692e142afc6b178470bd8e16d080e91497658c20e2824847906020016108df565b6000805160206125a38339815191526114e681611b46565b6000805160206125e38339815191526115008160006110fa565b1561151d5760405162461bcd60e51b81526004016108a5906123ef565b6000805160206125e3833981519152600081905260036020527feaea521b0fa1c79f9189cdc6d8d5f17d784b28b30b94868dd16f50216f20ffd25460ff16156115785760405162461bcd60e51b81526004016108a59061243c565b6115906000805160206125e383398151915285611b68565b6000805160206125e3833981519152600052600360209081527feaea521b0fa1c79f9189cdc6d8d5f17d784b28b30b94868dd16f50216f20ffd2805460ff191660011790556040516001600160a01b03861681527fd79838a02a85292deb7f2e9e20a140c1313678e1c21a2117d99df07532150a7b910160405180910390a150505050565b600061162083610f90565b158015611633575061163182610f90565b155b61164f5760405162461bcd60e51b81526004016108a59061234e565b50600192915050565b611660611aec565b806001600160a01b038116610e115760405162461bcd60e51b81526004016108a5906123a2565b60008051602061258383398151915261169f81611b46565b826001600160a01b0381166116c65760405162461bcd60e51b81526004016108a5906123a2565b836001600160a01b0316306001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561170e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117329190612499565b6001600160a01b0316148061174b575061174b84611ad2565b8061175a575061175a846110e4565b156117d95760405162461bcd60e51b815260206004820152604360248201527f4d50524f4d61737465724469737472696275746f723a204163636f756e74206860448201527f6173206120726f6c6520616e642063616e6e6f7420626520626c6f636b6c69736064820152621d195960ea1b608482015260a4016108a5565b50506001600160a01b03919091166000908152600460205260409020805460ff1916911515919091179055565b61180e611aec565b6001600160a01b0381166118735760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108a5565b61187c81611c52565b50565b60008051602061258383398151915261189781611b46565b826001600160a01b0381166118be5760405162461bcd60e51b81526004016108a5906123a2565b50506001600160a01b03919091166000908152600560205260409020805460ff1916911515919091179055565b60008051602061260383398151915261190381611b46565b600082116119535760405162461bcd60e51b815260206004820152601d60248201527f616d6f756e74206d7573742062652067726561746572207468616e203000000060448201526064016108a5565b6006544210156119b25760405162461bcd60e51b815260206004820152603660248201526000805160206125c38339815191526044820152751a5bdb881a5cc81b9bdd08195b98589b1959081e595d60521b60648201526084016108a5565b6119ba611cdb565b821115611a125760405162461bcd60e51b815260206004820152603260248201526000805160206125c38339815191526044820152711a5bdb881b1a5b5a5d08195e18d95959195960721b60648201526084016108a5565b6002546040516340c10f1960e01b81526001600160a01b03858116600483015260248201859052909116906340c10f1990604401600060405180830381600087803b158015611a6057600080fd5b505af1158015611a74573d6000803e3d6000fd5b505050508160076000828254611a8a919061230b565b90915550506040518281526001600160a01b038416907fb649c98f58055c520df0dcb5709eff2e931217ff2fb1e21376130d31bbb1c0af9060200160405180910390a2505050565b600061050e600080516020612583833981519152836110fa565b6001546001600160a01b03163314610f8e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108a5565b61187c8133611cf6565b60006112da82846122bc565b60006112da82846122f4565b611b7282826110fa565b611be9576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055611ba83390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b611bf782826110fa565b15611be9576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006001600160a01b038216611cbc57506001919050565b506001600160a01b031660009081526005602052604090205460ff1690565b6000611cf1600754611ceb610587565b90611d4f565b905090565b611d0082826110fa565b611be957611d0d81611d5b565b611d18836020611d6d565b604051602001611d299291906124da565b60408051601f198184030181529082905262461bcd60e51b82526108a59160040161254f565b60006112da82846122a9565b606061050e6001600160a01b03831660145b60606000611d7c8360026122f4565b611d8790600261230b565b67ffffffffffffffff811115611d9f57611d9f612002565b6040519080825280601f01601f191660200182016040528015611dc9576020820181803683370190505b509050600360fc1b81600081518110611de457611de46122de565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611e1357611e136122de565b60200101906001600160f81b031916908160001a9053506000611e378460026122f4565b611e4290600161230b565b90505b6001811115611eba576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110611e7657611e766122de565b1a60f81b828281518110611e8c57611e8c6122de565b60200101906001600160f81b031916908160001a90535060049490941c93611eb38161231e565b9050611e45565b5083156112da5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108a5565b600060208284031215611f1b57600080fd5b81356001600160e01b0319811681146112da57600080fd5b602080825282518282018190526000919060409081850190868401855b82811015611f7557815180518552860151868501529284019290850190600101611f50565b5091979650505050505050565b600060208284031215611f9457600080fd5b5035919050565b60008060408385031215611fae57600080fd5b50508035926020909101359150565b6001600160a01b038116811461187c57600080fd5b60008060408385031215611fe557600080fd5b823591506020830135611ff781611fbd565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561204157612041612002565b604052919050565b600067ffffffffffffffff82111561206357612063612002565b5060051b60200190565b600082601f83011261207e57600080fd5b8135602061209361208e83612049565b612018565b8083825260208201915060208460051b8701019350868411156120b557600080fd5b602086015b848110156120d157803583529183019183016120ba565b509695505050505050565b600080604083850312156120ef57600080fd5b823567ffffffffffffffff8082111561210757600080fd5b818501915085601f83011261211b57600080fd5b8135602061212b61208e83612049565b82815260059290921b8401810191818101908984111561214a57600080fd5b948201945b8386101561217157853561216281611fbd565b8252948201949082019061214f565b9650508601359250508082111561218757600080fd5b506121948582860161206d565b9150509250929050565b6000602082840312156121b057600080fd5b81356112da81611fbd565b6000806000606084860312156121d057600080fd5b83356121db81611fbd565b925060208401356121eb81611fbd565b915060408401356121fb81611fbd565b809150509250925092565b6000806040838503121561221957600080fd5b823561222481611fbd565b946020939093013593505050565b6000806040838503121561224557600080fd5b823561225081611fbd565b91506020830135611ff781611fbd565b6000806040838503121561227357600080fd5b823561227e81611fbd565b915060208301358015158114611ff757600080fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111561050e5761050e612293565b6000826122d957634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b808202811582820484141761050e5761050e612293565b8082018082111561050e5761050e612293565b60008161232d5761232d612293565b506000190190565b60006020828403121561234757600080fd5b5051919050565b60208082526034908201527f4d50524f4d61737465724469737472696275746f723a20416374696f6e206f6e60408201527308189b1bd8dadb1a5cdd1959081858d8dbdd5b9d60621b606082015260800190565b6020808252602d908201527f4d50524f4d61737465724469737472696275746f723a20416374696f6e206f6e60408201526c2061646472657373207a65726f60981b606082015260800190565b6020808252602d908201527f4d50524f4d61737465724469737472696275746f723a20526f6c65206973206160408201526c1b1c9958591e48189d5c9b9959609a1b606082015260800190565b6020808252603e908201527f4d50524f4d61737465724469737472696275746f723a20526f6c6520616c726560408201527f616479206772616e74656420746f20616e6f74686572206163636f756e740000606082015260800190565b6000602082840312156124ab57600080fd5b81516112da81611fbd565b60005b838110156124d15781810151838201526020016124b9565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516125128160178501602088016124b6565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516125438160288401602088016124b6565b01602801949350505050565b602081526000825180602084015261256e8160408501602087016124b6565b601f01601f1916919091016040019291505056fef94103142c1baabe9ac2b5d1487bf783de9e69cfeea9a72f5c9c94afd7877b8c6ee0f19c3526ca65945666b9437299b6a1b226cdffcd62f34d1cbc222cb026824d50524f4d61737465724469737472696275746f723a204469737472696275745afa424c0b6204848cb71c5aa5f8da1afaf45d645ada516ab6c53bb3ff616cffb19c0b5de53e6e8b2996523385ad2b2e358ef774bb7335734b02556c8b75f198a264697066735822122082500f0669a15f863c873b0eecfa357019769a54600554b0ee7657a776ff9fb764736f6c63430008160033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000003a1b656565e7c20aa4fadd4338f5fa73585a62b
-----Decoded View---------------
Arg [0] : _owner (address): 0x03A1b656565E7c20aA4fadD4338f5Fa73585a62b
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000003a1b656565e7c20aa4fadd4338f5fa73585a62b
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.