Feature Tip: Add private address tag to any address under My Name Tag !
Latest 25 from a total of 7,081 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Transfer | 22577194 | 270 days ago | IN | 0.00005 ETH | 0.00005367 | ||||
| Withdraw | 21691919 | 394 days ago | IN | 0 ETH | 0.00234977 | ||||
| Withdraw | 20517396 | 558 days ago | IN | 0 ETH | 0.00057249 | ||||
| Withdraw | 19208889 | 741 days ago | IN | 0 ETH | 0.01039074 | ||||
| Withdraw | 18964014 | 775 days ago | IN | 0 ETH | 0.01716693 | ||||
| Withdraw | 18937340 | 779 days ago | IN | 0 ETH | 0.00830866 | ||||
| Withdraw | 18571964 | 830 days ago | IN | 0 ETH | 0.02915094 | ||||
| Withdraw | 18532951 | 835 days ago | IN | 0 ETH | 0.01523612 | ||||
| Withdraw | 18524251 | 837 days ago | IN | 0 ETH | 0.01008708 | ||||
| Withdraw | 18470923 | 844 days ago | IN | 0 ETH | 0.01728624 | ||||
| Withdraw | 18449698 | 847 days ago | IN | 0 ETH | 0.00885207 | ||||
| Withdraw | 18360631 | 860 days ago | IN | 0 ETH | 0.00357811 | ||||
| Withdraw | 18214424 | 880 days ago | IN | 0 ETH | 0.00698506 | ||||
| Withdraw | 18214422 | 880 days ago | IN | 0 ETH | 0.00865221 | ||||
| Withdraw | 18164033 | 887 days ago | IN | 0 ETH | 0.0134928 | ||||
| Withdraw | 17717048 | 950 days ago | IN | 0 ETH | 0.01174215 | ||||
| Withdraw | 17592138 | 967 days ago | IN | 0 ETH | 0.01474571 | ||||
| Withdraw | 17508474 | 979 days ago | IN | 0 ETH | 0.00722196 | ||||
| Withdraw | 17377612 | 997 days ago | IN | 0 ETH | 0.01473684 | ||||
| Withdraw | 17301358 | 1008 days ago | IN | 0 ETH | 0.02130835 | ||||
| Withdraw | 17171685 | 1026 days ago | IN | 0 ETH | 0.0258708 | ||||
| Withdraw | 17031250 | 1046 days ago | IN | 0 ETH | 0.01055376 | ||||
| Withdraw | 17031132 | 1046 days ago | IN | 0 ETH | 0.01360881 | ||||
| Withdraw | 17022730 | 1048 days ago | IN | 0 ETH | 0.01025449 | ||||
| Withdraw | 16880036 | 1068 days ago | IN | 0 ETH | 0.00633063 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Transfer | 15727773 | 1229 days ago | 32 ETH | ||||
| Transfer | 15727773 | 1229 days ago | 32 ETH | ||||
| Deposit | 15727641 | 1229 days ago | 0.20022802 ETH | ||||
| Deposit | 15727632 | 1229 days ago | 0.74531 ETH | ||||
| Deposit | 15727628 | 1229 days ago | 0.74531 ETH | ||||
| Deposit | 15727622 | 1229 days ago | 0.74531 ETH | ||||
| Deposit | 15727617 | 1229 days ago | 0.74531 ETH | ||||
| Deposit | 15727607 | 1229 days ago | 0.74531 ETH | ||||
| Deposit | 15727604 | 1229 days ago | 0.74531 ETH | ||||
| Deposit | 15727600 | 1229 days ago | 0.74531 ETH | ||||
| Deposit | 15727587 | 1229 days ago | 0.74531 ETH | ||||
| Deposit | 15727570 | 1229 days ago | 0.74531 ETH | ||||
| Transfer | 15712170 | 1231 days ago | 0.00562898 ETH | ||||
| Transfer | 15712170 | 1231 days ago | 0.00562898 ETH | ||||
| Transfer | 15699995 | 1233 days ago | 0.00301602 ETH | ||||
| Transfer | 15699995 | 1233 days ago | 0.00301602 ETH | ||||
| Deposit | 15699974 | 1233 days ago | 0.00301602 ETH | ||||
| Transfer | 15677371 | 1236 days ago | 0.12499999 ETH | ||||
| Transfer | 15677371 | 1236 days ago | 0.12499999 ETH | ||||
| Transfer | 15677034 | 1236 days ago | 24.74968762 ETH | ||||
| Transfer | 15677034 | 1236 days ago | 24.74968762 ETH | ||||
| Transfer | 15670950 | 1237 days ago | 0.22184288 ETH | ||||
| Transfer | 15670950 | 1237 days ago | 0.22184288 ETH | ||||
| Transfer | 15648371 | 1240 days ago | 65.61624304 ETH | ||||
| Transfer | 15648371 | 1240 days ago | 65.61624304 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
AlchemistEth
Compiler Version
v0.6.12+commit.27d51765
Optimization Enabled:
Yes with 999999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;
//import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {Math} from "@openzeppelin/contracts/math/Math.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol";
import {CDP} from "./libraries/alchemist/CDP.sol";
import {FixedPointMath} from "./libraries/FixedPointMath.sol";
import {ITransmuter} from "./interfaces/ITransmuter.sol";
import {IMintableERC20} from "./interfaces/IMintableERC20.sol";
import {IChainlink} from "./interfaces/IChainlink.sol";
import {IVaultAdapter} from "./interfaces/IVaultAdapter.sol";
import {Vault} from "./libraries/alchemist/Vault.sol";
import {IWETH9} from "./interfaces/IWETH9.sol";
import {AlEth} from "./AlEth.sol";
// ERC20,removing ERC20 from the alchemist
// ___ __ __ _ ___ __ _
// / _ | / / ____ / / ___ __ _ (_) __ __ / _ \ ____ ___ ___ ___ ___ / /_ ___ (_)
// / __ | / / / __/ / _ \/ -_) / ' \ / / \ \ / / ___/ / __// -_) (_-</ -_) / _ \/ __/ (_-< _
// /_/ |_|/_/ \__/ /_//_/\__/ /_/_/_//_/ /_\_\ /_/ /_/ \__/ /___/\__/ /_//_/\__/ /___/(_)
//
// ___ __ ______ __ __ _______ .___ ___. __ _______..___________.
// / \ | | / || | | | | ____|| \/ | | | / || |
// / ^ \ | | | ,----'| |__| | | |__ | \ / | | | | (----``---| |----`
// / /_\ \ | | | | | __ | | __| | |\/| | | | \ \ | |
// / _____ \ | `----.| `----.| | | | | |____ | | | | | | .----) | | |
// /__/ \__\ |_______| \______||__| |__| |_______||__| |__| |__| |_______/ |__|
contract AlchemistEth is ReentrancyGuard {
using CDP for CDP.Data;
using FixedPointMath for FixedPointMath.FixedDecimal;
using Vault for Vault.Data;
using Vault for Vault.List;
using SafeERC20 for IMintableERC20;
using SafeMath for uint256;
using Address for address;
address public constant ZERO_ADDRESS = address(0);
/// @dev Resolution for all fixed point numeric parameters which represent percents. The resolution allows for a
/// granularity of 0.01% increments.
uint256 public constant PERCENT_RESOLUTION = 10000;
/// @dev The minimum value that the collateralization limit can be set to by the governance. This is a safety rail
/// to prevent the collateralization from being set to a value which breaks the system.
///
/// This value is equal to 100%.
///
/// IMPORTANT: This constant is a raw FixedPointMath.FixedDecimal value and assumes a resolution of 64 bits. If the
/// resolution for the FixedPointMath library changes this constant must change as well.
uint256 public constant MINIMUM_COLLATERALIZATION_LIMIT = 1000000000000000000;
/// @dev The maximum value that the collateralization limit can be set to by the governance. This is a safety rail
/// to prevent the collateralization from being set to a value which breaks the system.
///
/// This value is equal to 400%.
///
/// IMPORTANT: This constant is a raw FixedPointMath.FixedDecimal value and assumes a resolution of 64 bits. If the
/// resolution for the FixedPointMath library changes this constant must change as well.
uint256 public constant MAXIMUM_COLLATERALIZATION_LIMIT = 4000000000000000000;
event GovernanceUpdated(
address governance
);
event PendingGovernanceUpdated(
address pendingGovernance
);
event SentinelUpdated(
address sentinel
);
event TransmuterUpdated(
address transmuter
);
event RewardsUpdated(
address treasury
);
event HarvestFeeUpdated(
uint256 fee
);
event CollateralizationLimitUpdated(
uint256 limit
);
event EmergencyExitUpdated(
bool status
);
event ConversionPauseUpdated(
bool status
);
event ActiveVaultUpdated(
IVaultAdapter indexed adapter
);
event FundsHarvested(
uint256 withdrawnAmount,
uint256 decreasedValue
);
event FundsRecalled(
uint256 indexed vaultId,
uint256 withdrawnAmount,
uint256 decreasedValue
);
event FundsFlushed(
uint256 amount
);
event TokensDeposited(
address indexed account,
uint256 amount
);
event TokensWithdrawn(
address indexed account,
uint256 requestedAmount,
uint256 withdrawnAmount,
uint256 decreasedValue
);
event TokensRepaid(
address indexed account,
uint256 parentAmount,
uint256 childAmount
);
event TokensLiquidated(
address indexed account,
uint256 requestedAmount,
uint256 withdrawnAmount,
uint256 decreasedValue
);
event LoanMinted(
address indexed account,
uint256 mintedAmount,
address syntheticAddress
);
event CollateralConverted(
address user,
uint256 covertedAmount
);
event KeepersSet(
address[] accounts,
bool[] flag
);
/// @dev The token that this contract is using as the parent asset.
IMintableERC20 public token;
/// @dev The address off the WETH contract.
address public weth;
/// @dev The token that this contract is using as the child asset.
AlEth public xtoken;
/// @dev The address of the account which currently has administrative capabilities over this contract.
address public governance;
/// @dev The address of the pending governance.
address public pendingGovernance;
/// @dev The address of the account which can initiate an emergency withdraw of funds in a vault.
address public sentinel;
/// @dev The address of the contract which will transmute synthetic tokens back into native tokens.
address public transmuter;
/// @dev The address of the contract which will receive fees.
address public rewards;
/// @dev The percent of each profitable harvest that will go to the rewards contract.
uint256 public harvestFee;
/// @dev The total amount the native token deposited into the system that is owned by external users.
uint256 public totalDeposited;
/// @dev when movemetns are bigger than this number flush is activated.
uint256 public flushActivator;
/// @dev A flag indicating if the contract has been initialized yet.
bool public initialized;
/// @dev A flag indicating if deposits and flushes should be halted and if all parties should be able to recall
/// from the active vault.
bool public emergencyExit;
bool public pauseConvert;
/// @dev The context shared between the CDPs.
CDP.Context private _ctx;
/// @dev A mapping of all of the user CDPs. If a user wishes to have multiple CDPs they will have to either
/// create a new address or set up a proxy contract that interfaces with this contract.
mapping(address => CDP.Data) private _cdps;
/// @dev A mapping of adapter addresses to keep track of vault adapters that have already been added
mapping(address => bool) public adapters;
/// @dev A list of all of the vaults. The last element of the list is the vault that is currently being used for
/// deposits and withdraws. Vaults before the last element are considered inactive and are expected to be cleared.
Vault.List private _vaults;
/// @dev A list of addresses that can call flush and harvest
mapping(address => bool) public keepers;
constructor(
IMintableERC20 _token,
AlEth _xtoken,
address _governance,
address _sentinel
)
public
{
require(_governance != ZERO_ADDRESS, "Alchemist: governance address cannot be 0x0.");
require(_sentinel != ZERO_ADDRESS, "Alchemist: sentinel address cannot be 0x0.");
weth = address(_token);
token = _token;
xtoken = _xtoken;
governance = _governance;
sentinel = _sentinel;
flushActivator = 10000 ether;
emergencyExit = true;
pauseConvert = true;
uint256 COLL_LIMIT = MINIMUM_COLLATERALIZATION_LIMIT.mul(4);
_ctx.collateralizationLimit = FixedPointMath.FixedDecimal(COLL_LIMIT);
_ctx.accumulatedYieldWeight = FixedPointMath.FixedDecimal(0);
}
/// @dev Sets the pending governance.
///
/// This function reverts if the new pending governance is the zero address or the caller is not the current
/// governance. This is to prevent the contract governance being set to the zero address which would deadlock
/// privileged contract functionality.
///
/// @param _pendingGovernance the new pending governance.
function setPendingGovernance(address _pendingGovernance) external onlyGov {
require(_pendingGovernance != ZERO_ADDRESS, "Alchemist: governance address cannot be 0x0.");
pendingGovernance = _pendingGovernance;
emit PendingGovernanceUpdated(_pendingGovernance);
}
/// @dev Accepts the role as governance.
///
/// This function reverts if the caller is not the new pending governance.
function acceptGovernance() external {
require(msg.sender == pendingGovernance,"sender is not pendingGovernance");
address _pendingGovernance = pendingGovernance;
governance = _pendingGovernance;
emit GovernanceUpdated(_pendingGovernance);
}
function setSentinel(address _sentinel) external onlyGov {
require(_sentinel != ZERO_ADDRESS, "Alchemist: sentinel address cannot be 0x0.");
sentinel = _sentinel;
emit SentinelUpdated(_sentinel);
}
/// @dev Sets the transmuter.
///
/// This function reverts if the new transmuter is the zero address or the caller is not the current governance.
///
/// @param _transmuter the new transmuter.
function setTransmuter(address _transmuter) external onlyGov {
// Check that the transmuter address is not the zero address. Setting the transmuter to the zero address would break
// transfers to the address because of `safeTransfer` checks.
require(_transmuter != ZERO_ADDRESS, "Alchemist: transmuter address cannot be 0x0.");
transmuter = _transmuter;
emit TransmuterUpdated(_transmuter);
}
/// @dev Sets the flushActivator.
///
/// @param _flushActivator the new flushActivator.
function setFlushActivator(uint256 _flushActivator) external onlyGov {
flushActivator = _flushActivator;
}
/// @dev Sets the rewards contract.
///
/// This function reverts if the new rewards contract is the zero address or the caller is not the current governance.
///
/// @param _rewards the new rewards contract.
function setRewards(address _rewards) external onlyGov {
// Check that the rewards address is not the zero address. Setting the rewards to the zero address would break
// transfers to the address because of `safeTransfer` checks.
require(_rewards != ZERO_ADDRESS, "Alchemist: rewards address cannot be 0x0.");
rewards = _rewards;
emit RewardsUpdated(_rewards);
}
/// @dev Sets the harvest fee.
///
/// This function reverts if the caller is not the current governance.
///
/// @param _harvestFee the new harvest fee.
function setHarvestFee(uint256 _harvestFee) external onlyGov {
// Check that the harvest fee is within the acceptable range. Setting the harvest fee greater than 100% could
// potentially break internal logic when calculating the harvest fee.
require(_harvestFee <= PERCENT_RESOLUTION, "Alchemist: harvest fee above maximum.");
harvestFee = _harvestFee;
emit HarvestFeeUpdated(_harvestFee);
}
/// @dev Sets the collateralization limit.
///
/// This function reverts if the caller is not the current governance or if the collateralization limit is outside
/// of the accepted bounds.
///
/// @param _limit the new collateralization limit.
function setCollateralizationLimit(uint256 _limit) external onlyGov {
require(_limit >= MINIMUM_COLLATERALIZATION_LIMIT, "Alchemist: collateralization limit below minimum.");
require(_limit <= MAXIMUM_COLLATERALIZATION_LIMIT, "Alchemist: collateralization limit above maximum.");
_ctx.collateralizationLimit = FixedPointMath.FixedDecimal(_limit);
emit CollateralizationLimitUpdated(_limit);
}
/// @dev Sets if the contract should enter emergency exit mode.
///
/// @param _emergencyExit if the contract should enter emergency exit mode.
function setEmergencyExit(bool _emergencyExit) external {
require(msg.sender == governance || msg.sender == sentinel, "!governance && !sentinel");
emergencyExit = _emergencyExit;
emit EmergencyExitUpdated(_emergencyExit);
}
/// @dev Sets if the contract should pause conversions.
///
/// @param _pauseConvert if the contract should pause conversions.
function setPauseConvert(bool _pauseConvert) external {
require(msg.sender == governance || msg.sender == sentinel, "!governance && !sentinel");
pauseConvert = _pauseConvert;
emit ConversionPauseUpdated(_pauseConvert);
}
/// @dev Sets the addresses of the keepers list.
///
/// @param accounts the accounts to set.
/// @param flags the flags for the accounts.
function setKeepers(address[] calldata accounts, bool[] calldata flags) external onlyGov {
uint256 numAccounts = accounts.length;
for (uint256 i = 0; i < numAccounts; i++) {
keepers[accounts[i]] = flags[i];
}
emit KeepersSet(accounts, flags);
}
/// @dev Gets the collateralization limit.
///
/// The collateralization limit is the minimum ratio of collateral to debt that is allowed by the system.
///
/// @return the collateralization limit.
function collateralizationLimit() external view returns (FixedPointMath.FixedDecimal memory) {
return _ctx.collateralizationLimit;
}
/// @dev Initializes the contract.
///
/// This function checks that the transmuter and rewards have been set and sets up the active vault.
///
/// @param _adapter the vault adapter of the active vault.
function initialize(IVaultAdapter _adapter) external onlyGov {
require(!initialized, "Alchemist: already initialized");
require(transmuter != ZERO_ADDRESS, "Alchemist: cannot initialize transmuter address to 0x0");
require(rewards != ZERO_ADDRESS, "Alchemist: cannot initialize rewards address to 0x0");
_updateActiveVault(_adapter);
initialized = true;
}
/// @dev Migrates the system to a new vault.
///
/// This function reverts if the vault adapter is the zero address, if the token that the vault adapter accepts
/// is not the token that this contract defines as the parent asset, or if the contract has not yet been initialized.
///
/// @param _adapter the adapter for the vault the system will migrate to.
function migrate(IVaultAdapter _adapter) external expectInitialized onlyGov {
_updateActiveVault(_adapter);
}
/// @dev Harvests yield from a vault.
///
/// @param _vaultId the identifier of the vault to harvest from.
///
/// @return the amount of funds that were harvested from the vault.
function harvest(uint256 _vaultId) external expectInitialized onlyKeeper returns (uint256, uint256) {
Vault.Data storage _vault = _vaults.get(_vaultId);
(uint256 _harvestedAmount, uint256 _decreasedValue) = _vault.harvest(address(this));
if (_harvestedAmount > 0) {
uint256 _feeAmount = _harvestedAmount.mul(harvestFee).div(PERCENT_RESOLUTION);
uint256 _distributeAmount = _harvestedAmount.sub(_feeAmount);
FixedPointMath.FixedDecimal memory _weight = FixedPointMath.fromU256(_distributeAmount).div(totalDeposited);
_ctx.accumulatedYieldWeight = _ctx.accumulatedYieldWeight.add(_weight);
if (_feeAmount > 0) {
token.safeTransfer(rewards, _feeAmount);
}
if (_distributeAmount > 0) {
_distributeToTransmuter(_distributeAmount);
}
}
emit FundsHarvested(_harvestedAmount, _decreasedValue);
return (_harvestedAmount, _decreasedValue);
}
/// @dev Recalls an amount of deposited funds from a vault to this contract.
///
/// @param _vaultId the identifier of the recall funds from.
///
/// @return the amount of funds that were recalled from the vault to this contract and the decreased vault value.
function recall(uint256 _vaultId, uint256 _amount) external nonReentrant expectInitialized returns (uint256, uint256) {
return _recallFunds(_vaultId, _amount);
}
/// @dev Recalls all the deposited funds from a vault to this contract.
///
/// @param _vaultId the identifier of the recall funds from.
///
/// @return the amount of funds that were recalled from the vault to this contract and the decreased vault value.
function recallAll(uint256 _vaultId) external nonReentrant expectInitialized returns (uint256, uint256) {
Vault.Data storage _vault = _vaults.get(_vaultId);
return _recallFunds(_vaultId, _vault.totalDeposited);
}
/// @dev Flushes buffered tokens to the active vault.
///
/// This function reverts if an emergency exit is active. This is in place to prevent the potential loss of
/// additional funds.
///
/// @return the amount of tokens flushed to the active vault.
function flush() external nonReentrant expectInitialized onlyKeeper returns (uint256) {
// Prevent flushing to the active vault when an emergency exit is enabled to prevent potential loss of funds if
// the active vault is poisoned for any reason.
require(!emergencyExit, "emergency pause enabled");
return flushActiveVault();
}
/// @dev Internal function to flush buffered tokens to the active vault.
///
/// This function reverts if an emergency exit is active. This is in place to prevent the potential loss of
/// additional funds.
///
/// @return the amount of tokens flushed to the active vault.
function flushActiveVault() internal returns (uint256) {
Vault.Data storage _activeVault = _vaults.last();
uint256 _depositedAmount = _activeVault.depositAll();
emit FundsFlushed(_depositedAmount);
return _depositedAmount;
}
/// @dev Deposits collateral into a CDP.
///
/// @param _amount the amount of collateral to deposit.
function deposit(uint256 _amount, bool asEth) external payable nonReentrant noContractAllowed expectInitialized {
require(!emergencyExit, "emergency pause enabled");
CDP.Data storage _cdp = _cdps[msg.sender];
_cdp.update(_ctx);
if (asEth) {
require(_amount == msg.value, "_amount != msg.value");
IWETH9(weth).deposit{value: _amount}();
} else {
require(msg.value == 0, "msg.value != 0");
token.safeTransferFrom(msg.sender, address(this), _amount);
}
if(_amount >= flushActivator) {
flushActiveVault();
}
totalDeposited = totalDeposited.add(_amount);
_cdp.totalDeposited = _cdp.totalDeposited.add(_amount);
_cdp.lastDeposit = block.number;
emit TokensDeposited(msg.sender, _amount);
}
/// @dev Attempts to withdraw part of a CDP's collateral.
///
/// This function reverts if a deposit into the CDP was made in the same block. This is to prevent flash loan attacks
/// on other internal or external systems.
///
/// @param _amount the amount of collateral to withdraw.
function withdraw(uint256 _amount, bool asEth) external nonReentrant noContractAllowed expectInitialized returns (uint256, uint256) {
CDP.Data storage _cdp = _cdps[msg.sender];
require(block.number > _cdp.lastDeposit, "");
_cdp.update(_ctx);
(uint256 _withdrawnAmount, uint256 _decreasedValue) = _withdrawFundsTo(msg.sender, _amount, asEth);
_cdp.totalDeposited = _cdp.totalDeposited.sub(_decreasedValue, "Exceeds withdrawable amount");
_cdp.checkHealth(_ctx, "Action blocked: unhealthy collateralization ratio");
emit TokensWithdrawn(msg.sender, _amount, _withdrawnAmount, _decreasedValue);
return (_withdrawnAmount, _decreasedValue);
}
/// @dev Repays debt with the native and or synthetic token.
///
/// An approval is required to transfer native tokens to the transmuter.
function repay(uint256 _collateralAmount, uint256 _syntheticAmount, bool collateralAsEth) external payable nonReentrant noContractAllowed expectInitialized {
if ((!collateralAsEth || (collateralAsEth && _collateralAmount == 0)) && msg.value != 0) {
revert("blackhole ETH");
}
CDP.Data storage _cdp = _cdps[msg.sender];
_cdp.update(_ctx);
if (_collateralAmount > 0) {
if (collateralAsEth) {
require(_collateralAmount == msg.value, "_collateralAmount != msg.value");
IWETH9(weth).deposit{value: _collateralAmount}();
} else {
token.safeTransferFrom(msg.sender, address(this), _collateralAmount);
}
_distributeToTransmuter(_collateralAmount);
}
if (_syntheticAmount > 0) {
xtoken.burnFrom(msg.sender, _syntheticAmount);
//lower debt cause burn
xtoken.lowerHasMinted(_syntheticAmount);
}
uint256 _totalAmount = _collateralAmount.add(_syntheticAmount);
_cdp.totalDebt = _cdp.totalDebt.sub(_totalAmount);
emit TokensRepaid(msg.sender, _collateralAmount, _syntheticAmount);
}
/// @dev Attempts to liquidate part of a CDP's collateral to pay back its debt.
///
/// @param _amount the amount of collateral to attempt to liquidate.
function liquidate(uint256 _amount) external nonReentrant noContractAllowed expectInitialized returns (uint256, uint256) {
CDP.Data storage _cdp = _cdps[msg.sender];
_cdp.update(_ctx);
// don't attempt to liquidate more than is possible
if(_amount > _cdp.totalDebt){
_amount = _cdp.totalDebt;
}
(uint256 _withdrawnAmount, uint256 _decreasedValue) = _withdrawFundsTo(payable(address(this)), _amount, false);
//changed to new transmuter compatibillity
_distributeToTransmuter(_withdrawnAmount);
_cdp.totalDeposited = _cdp.totalDeposited.sub(_decreasedValue, "");
_cdp.totalDebt = _cdp.totalDebt.sub(_withdrawnAmount, "");
emit TokensLiquidated(msg.sender, _amount, _withdrawnAmount, _decreasedValue);
return (_withdrawnAmount, _decreasedValue);
}
/// @dev Converts ETH/WETH to alETH
///
/// @param _amount the amount of collateral to convert.
function convert(uint256 _amount, bool asEth) external payable nonReentrant noContractAllowed expectInitialized {
require(!pauseConvert, "Alchemist: conversions are paused.");
if (asEth) {
require(_amount == msg.value, "_amount != msg.value");
IWETH9(weth).deposit{value: _amount}();
} else {
require(msg.value == 0, "msg.value != 0");
token.safeTransferFrom(msg.sender, address(this), _amount);
}
// TODO test lowerHasMinted
xtoken.mint(msg.sender, _amount);
_distributeToTransmuter(_amount);
require(xtoken.hasMinted(address(this)) <= xtoken.ceiling(address(this)),"AlETH: Alchemist's ceiling was breached.");
emit CollateralConverted(msg.sender, _amount);
}
/// @dev Recover eth sent directly to the Alchemist
///
/// only callable by governance
function recoverLostFunds() external onlyGov() {
payable(governance).transfer(address(this).balance);
}
/// @dev Mints synthetic tokens by either claiming credit or increasing the debt.
///
/// Claiming credit will take priority over increasing the debt.
///
/// This function reverts if the debt is increased and the CDP health check fails.
///
/// @param _amount the amount of alchemic tokens to borrow.
function mint(uint256 _amount) external nonReentrant noContractAllowed expectInitialized {
CDP.Data storage _cdp = _cdps[msg.sender];
_cdp.update(_ctx);
uint256 _totalCredit = _cdp.totalCredit;
if (_totalCredit < _amount) {
uint256 _remainingAmount = _amount.sub(_totalCredit);
_cdp.totalDebt = _cdp.totalDebt.add(_remainingAmount);
_cdp.totalCredit = 0;
_cdp.checkHealth(_ctx, "Alchemist: Loan-to-value ratio breached");
} else {
_cdp.totalCredit = _totalCredit.sub(_amount);
}
xtoken.mint(msg.sender, _amount);
require(xtoken.hasMinted(address(this)) <= xtoken.ceiling(address(this)),"AlETH: Alchemist's ceiling was breached.");
emit LoanMinted(msg.sender, _amount, address(xtoken));
}
/// @dev Gets the number of vaults in the vault list.
///
/// @return the vault count.
function vaultCount() external view returns (uint256) {
return _vaults.length();
}
/// @dev Get the adapter of a vault.
///
/// @param _vaultId the identifier of the vault.
///
/// @return the vault adapter.
function getVaultAdapter(uint256 _vaultId) external view returns (IVaultAdapter) {
Vault.Data storage _vault = _vaults.get(_vaultId);
return _vault.adapter;
}
/// @dev Get the total amount of the parent asset that has been deposited into a vault.
///
/// @param _vaultId the identifier of the vault.
///
/// @return the total amount of deposited tokens.
function getVaultTotalDeposited(uint256 _vaultId) external view returns (uint256) {
Vault.Data storage _vault = _vaults.get(_vaultId);
return _vault.totalDeposited;
}
/// @dev Get the total amount of collateral deposited into a CDP.
///
/// @param _account the user account of the CDP to query.
///
/// @return the deposited amount of tokens.
function getCdpTotalDeposited(address _account) external view returns (uint256) {
CDP.Data storage _cdp = _cdps[_account];
return _cdp.totalDeposited;
}
/// @dev Get the total amount of alchemic tokens borrowed from a CDP.
///
/// @param _account the user account of the CDP to query.
///
/// @return the borrowed amount of tokens.
function getCdpTotalDebt(address _account) external view returns (uint256) {
CDP.Data storage _cdp = _cdps[_account];
return _cdp.getUpdatedTotalDebt(_ctx);
}
/// @dev Get the total amount of credit that a CDP has.
///
/// @param _account the user account of the CDP to query.
///
/// @return the amount of credit.
function getCdpTotalCredit(address _account) external view returns (uint256) {
CDP.Data storage _cdp = _cdps[_account];
return _cdp.getUpdatedTotalCredit(_ctx);
}
/// @dev Gets the last recorded block of when a user made a deposit into their CDP.
///
/// @param _account the user account of the CDP to query.
///
/// @return the block number of the last deposit.
function getCdpLastDeposit(address _account) external view returns (uint256) {
CDP.Data storage _cdp = _cdps[_account];
return _cdp.lastDeposit;
}
/// @dev sends tokens to the transmuter
///
/// benefit of great nation of transmuter
function _distributeToTransmuter(uint256 amount) internal {
token.approve(transmuter,amount);
ITransmuter(transmuter).distribute(address(this),amount);
// lower debt cause of 'burn'
xtoken.lowerHasMinted(amount);
}
/// @dev Checks that caller is not a eoa.
///
/// This is used to prevent contracts from interacting.
modifier noContractAllowed() {
require(!address(msg.sender).isContract() && msg.sender == tx.origin, "Sorry we do not accept contract!");
_;
}
/// @dev Checks that the contract is in an initialized state.
///
/// This is used over a modifier to reduce the size of the contract
modifier expectInitialized() {
require(initialized, "Alchemist: not initialized.");
_;
}
/// @dev Checks that the current message sender or caller is a specific address.
///
/// @param _expectedCaller the expected caller.
function _expectCaller(address _expectedCaller) internal {
require(msg.sender == _expectedCaller, "");
}
/// @dev Checks that the current message sender or caller is the governance address.
///
///
modifier onlyGov() {
require(msg.sender == governance, "Alchemist: only governance.");
_;
}
/// @dev Checks that the current message sender or caller is the governance address.
///
///
modifier onlyKeeper() {
require(keepers[msg.sender], "Alchemist: only keepers.");
_;
}
/// @dev Updates the active vault.
///
/// This function reverts if the vault adapter is the zero address, if the token that the vault adapter accepts
/// is not the token that this contract defines as the parent asset, or if the contract has not yet been initialized.
///
/// @param _adapter the adapter for the new active vault.
function _updateActiveVault(IVaultAdapter _adapter) internal {
require(_adapter != IVaultAdapter(ZERO_ADDRESS), "Alchemist: active vault address cannot be 0x0.");
require(_adapter.token() == token, "Alchemist: token mismatch.");
require(!adapters[address(_adapter)], "Adapter already in use");
adapters[address(_adapter)] = true;
_vaults.push(Vault.Data({
adapter: _adapter,
totalDeposited: 0
}));
emit ActiveVaultUpdated(_adapter);
}
/// @dev Recalls an amount of funds from a vault to this contract.
///
/// @param _vaultId the identifier of the recall funds from.
/// @param _amount the amount of funds to recall from the vault.
///
/// @return the amount of funds that were recalled from the vault to this contract and the decreased vault value.
function _recallFunds(uint256 _vaultId, uint256 _amount) internal returns (uint256, uint256) {
require(emergencyExit || msg.sender == governance || _vaultId != _vaults.lastIndex(), "Alchemist: not an emergency, not governance, and user does not have permission to recall funds from active vault");
Vault.Data storage _vault = _vaults.get(_vaultId);
(uint256 _withdrawnAmount, uint256 _decreasedValue) = _vault.withdraw(address(this), _amount);
emit FundsRecalled(_vaultId, _withdrawnAmount, _decreasedValue);
return (_withdrawnAmount, _decreasedValue);
}
/// @dev Attempts to withdraw funds from the active vault to the recipient.
///
/// Funds will be first withdrawn from this contracts balance and then from the active vault. This function
/// is different from `recallFunds` in that it reduces the total amount of deposited tokens by the decreased
/// value of the vault.
///
/// @param _recipient the account to withdraw the funds to.
/// @param _amount the amount of funds to withdraw.
function _withdrawFundsTo(address payable _recipient, uint256 _amount, bool asEth) internal returns (uint256, uint256) {
// Pull the funds from the buffer.
uint256 _bufferedAmount = Math.min(_amount, token.balanceOf(address(this)));
if (_recipient != address(this)) {
if (asEth) {
IWETH9(weth).withdraw(_bufferedAmount);
_recipient.transfer(_bufferedAmount);
} else {
token.safeTransfer(_recipient, _bufferedAmount);
}
}
uint256 _totalWithdrawn = _bufferedAmount;
uint256 _totalDecreasedValue = _bufferedAmount;
uint256 _remainingAmount = _amount.sub(_bufferedAmount);
// Pull the remaining funds from the active vault.
if (_remainingAmount > 0) {
Vault.Data storage _activeVault = _vaults.last();
uint256 _withdrawnAmount = 0;
uint256 _decreasedValue = 0;
if (asEth) {
(_withdrawnAmount, _decreasedValue) = _activeVault.withdraw(
payable(address(this)),
_remainingAmount
);
IWETH9(weth).withdraw(_withdrawnAmount);
_recipient.transfer(_withdrawnAmount);
} else {
(_withdrawnAmount, _decreasedValue) = _activeVault.withdraw(
_recipient,
_remainingAmount
);
}
_totalWithdrawn = _totalWithdrawn.add(_withdrawnAmount);
_totalDecreasedValue = _totalDecreasedValue.add(_decreasedValue);
}
totalDeposited = totalDeposited.sub(_totalDecreasedValue);
return (_totalWithdrawn, _totalDecreasedValue);
}
receive() external payable {}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
* @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, so we distribute
return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor () internal {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2 <0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
// solhint-disable-next-line max-line-length
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
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) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
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) {
// 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) {
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) {
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) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @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) {
require(b <= a, "SafeMath: subtraction overflow");
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) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @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. 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) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
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) {
require(b > 0, "SafeMath: modulo by zero");
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) {
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.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* 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) {
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) {
require(b > 0, errorMessage);
return a % b;
}
}// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.12;
import {Math} from "@openzeppelin/contracts/math/Math.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol";
import {FixedPointMath} from "../FixedPointMath.sol";
import {IDetailedERC20} from "../../interfaces/IDetailedERC20.sol";
import "hardhat/console.sol";
/// @title CDP
///
/// @dev A library which provides the CDP data struct and associated functions.
library CDP {
using CDP for Data;
using FixedPointMath for FixedPointMath.FixedDecimal;
using SafeERC20 for IDetailedERC20;
using SafeMath for uint256;
struct Context {
FixedPointMath.FixedDecimal collateralizationLimit;
FixedPointMath.FixedDecimal accumulatedYieldWeight;
}
struct Data {
uint256 totalDeposited;
uint256 totalDebt;
uint256 totalCredit;
uint256 lastDeposit;
FixedPointMath.FixedDecimal lastAccumulatedYieldWeight;
}
function update(Data storage _self, Context storage _ctx) internal {
uint256 _earnedYield = _self.getEarnedYield(_ctx);
if (_earnedYield > _self.totalDebt) {
uint256 _currentTotalDebt = _self.totalDebt;
_self.totalDebt = 0;
_self.totalCredit = _earnedYield.sub(_currentTotalDebt);
} else {
_self.totalDebt = _self.totalDebt.sub(_earnedYield);
}
_self.lastAccumulatedYieldWeight = _ctx.accumulatedYieldWeight;
}
/// @dev Assures that the CDP is healthy.
///
/// This function will revert if the CDP is unhealthy.
function checkHealth(Data storage _self, Context storage _ctx, string memory _msg) internal view {
require(_self.isHealthy(_ctx), _msg);
}
/// @dev Gets if the CDP is considered healthy.
///
/// A CDP is healthy if its collateralization ratio is greater than the global collateralization limit.
///
/// @return if the CDP is healthy.
function isHealthy(Data storage _self, Context storage _ctx) internal view returns (bool) {
return _ctx.collateralizationLimit.cmp(_self.getCollateralizationRatio(_ctx)) <= 0;
}
function getUpdatedTotalDebt(Data storage _self, Context storage _ctx) internal view returns (uint256) {
uint256 _unclaimedYield = _self.getEarnedYield(_ctx);
if (_unclaimedYield == 0) {
return _self.totalDebt;
}
uint256 _currentTotalDebt = _self.totalDebt;
if (_unclaimedYield >= _currentTotalDebt) {
return 0;
}
return _currentTotalDebt - _unclaimedYield;
}
function getUpdatedTotalCredit(Data storage _self, Context storage _ctx) internal view returns (uint256) {
uint256 _unclaimedYield = _self.getEarnedYield(_ctx);
if (_unclaimedYield == 0) {
return _self.totalCredit;
}
uint256 _currentTotalDebt = _self.totalDebt;
if (_unclaimedYield <= _currentTotalDebt) {
return 0;
}
return _self.totalCredit + (_unclaimedYield - _currentTotalDebt);
}
/// @dev Gets the amount of yield that a CDP has earned since the last time it was updated.
///
/// @param _self the CDP to query.
/// @param _ctx the CDP context.
///
/// @return the amount of earned yield.
function getEarnedYield(Data storage _self, Context storage _ctx) internal view returns (uint256) {
FixedPointMath.FixedDecimal memory _currentAccumulatedYieldWeight = _ctx.accumulatedYieldWeight;
FixedPointMath.FixedDecimal memory _lastAccumulatedYieldWeight = _self.lastAccumulatedYieldWeight;
if (_currentAccumulatedYieldWeight.cmp(_lastAccumulatedYieldWeight) == 0) {
return 0;
}
return _currentAccumulatedYieldWeight
.sub(_lastAccumulatedYieldWeight)
.mul(_self.totalDeposited)
.decode();
}
/// @dev Gets a CDPs collateralization ratio.
///
/// The collateralization ratio is defined as the ratio of collateral to debt. If the CDP has zero debt then this
/// will return the maximum value of a fixed point integer.
///
/// This function will use the updated total debt so an update before calling this function is not required.
///
/// @param _self the CDP to query.
///
/// @return a fixed point integer representing the collateralization ratio.
function getCollateralizationRatio(Data storage _self, Context storage _ctx)
internal view
returns (FixedPointMath.FixedDecimal memory)
{
uint256 _totalDebt = _self.getUpdatedTotalDebt(_ctx);
if (_totalDebt == 0) {
return FixedPointMath.maximumValue();
}
return FixedPointMath.fromU256(_self.totalDeposited).div(_totalDebt);
}
}//SPDX-License-Identifier: Unlicense
pragma solidity ^0.6.12;
library FixedPointMath {
uint256 public constant DECIMALS = 18;
uint256 public constant SCALAR = 10**DECIMALS;
struct FixedDecimal {
uint256 x;
}
function fromU256(uint256 value) internal pure returns (FixedDecimal memory) {
uint256 x;
require(value == 0 || (x = value * SCALAR) / SCALAR == value);
return FixedDecimal(x);
}
function maximumValue() internal pure returns (FixedDecimal memory) {
return FixedDecimal(uint256(-1));
}
function add(FixedDecimal memory self, FixedDecimal memory value) internal pure returns (FixedDecimal memory) {
uint256 x;
require((x = self.x + value.x) >= self.x);
return FixedDecimal(x);
}
function add(FixedDecimal memory self, uint256 value) internal pure returns (FixedDecimal memory) {
return add(self, fromU256(value));
}
function sub(FixedDecimal memory self, FixedDecimal memory value) internal pure returns (FixedDecimal memory) {
uint256 x;
require((x = self.x - value.x) <= self.x);
return FixedDecimal(x);
}
function sub(FixedDecimal memory self, uint256 value) internal pure returns (FixedDecimal memory) {
return sub(self, fromU256(value));
}
function mul(FixedDecimal memory self, uint256 value) internal pure returns (FixedDecimal memory) {
uint256 x;
require(value == 0 || (x = self.x * value) / value == self.x);
return FixedDecimal(x);
}
function div(FixedDecimal memory self, uint256 value) internal pure returns (FixedDecimal memory) {
require(value != 0);
return FixedDecimal(self.x / value);
}
function cmp(FixedDecimal memory self, FixedDecimal memory value) internal pure returns (int256) {
if (self.x < value.x) {
return -1;
}
if (self.x > value.x) {
return 1;
}
return 0;
}
function decode(FixedDecimal memory self) internal pure returns (uint256) {
return self.x / SCALAR;
}
}// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.12;
interface ITransmuter {
function distribute (address origin, uint256 amount) external;
}// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.12;
import {IDetailedERC20} from "./IDetailedERC20.sol";
interface IMintableERC20 is IDetailedERC20{
function mint(address _recipient, uint256 _amount) external;
function burnFrom(address account, uint256 amount) external;
function lowerHasMinted(uint256 amount)external;
}// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.12;
interface IChainlink {
function latestAnswer() external view returns (int256);
}// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.12;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./IDetailedERC20.sol";
/// Interface for all Vault Adapter implementations.
interface IVaultAdapter {
/// @dev Gets the token that the adapter accepts.
function token() external view returns (IDetailedERC20);
/// @dev The total value of the assets deposited into the vault.
function totalValue() external view returns (uint256);
/// @dev Deposits funds into the vault.
///
/// @param _amount the amount of funds to deposit.
function deposit(uint256 _amount) external;
/// @dev Attempts to withdraw funds from the wrapped vault.
///
/// The amount withdrawn to the recipient may be less than the amount requested.
///
/// @param _recipient the recipient of the funds.
/// @param _amount the amount of funds to withdraw.
function withdraw(address _recipient, uint256 _amount) external;
}// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.12;
//import "hardhat/console.sol";
import {Math} from "@openzeppelin/contracts/math/Math.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol";
import {IDetailedERC20} from "../../interfaces/IDetailedERC20.sol";
import {IVaultAdapter} from "../../interfaces/IVaultAdapter.sol";
import "hardhat/console.sol";
/// @title Pool
///
/// @dev A library which provides the Vault data struct and associated functions.
library Vault {
using Vault for Data;
using Vault for List;
using SafeERC20 for IDetailedERC20;
using SafeMath for uint256;
struct Data {
IVaultAdapter adapter;
uint256 totalDeposited;
}
struct List {
Data[] elements;
}
/// @dev Gets the total amount of assets deposited in the vault.
///
/// @return the total assets.
function totalValue(Data storage _self) internal view returns (uint256) {
return _self.adapter.totalValue();
}
/// @dev Gets the token that the vault accepts.
///
/// @return the accepted token.
function token(Data storage _self) internal view returns (IDetailedERC20) {
return IDetailedERC20(_self.adapter.token());
}
/// @dev Deposits funds from the caller into the vault.
///
/// @param _amount the amount of funds to deposit.
function deposit(Data storage _self, uint256 _amount) internal returns (uint256) {
// Push the token that the vault accepts onto the stack to save gas.
IDetailedERC20 _token = _self.token();
_token.safeTransfer(address(_self.adapter), _amount);
_self.adapter.deposit(_amount);
_self.totalDeposited = _self.totalDeposited.add(_amount);
return _amount;
}
/// @dev Deposits the entire token balance of the caller into the vault.
function depositAll(Data storage _self) internal returns (uint256) {
IDetailedERC20 _token = _self.token();
return _self.deposit(_token.balanceOf(address(this)));
}
/// @dev Withdraw deposited funds from the vault.
///
/// @param _recipient the account to withdraw the tokens to.
/// @param _amount the amount of tokens to withdraw.
function withdraw(Data storage _self, address _recipient, uint256 _amount) internal returns (uint256, uint256) {
(uint256 _withdrawnAmount, uint256 _decreasedValue) = _self.directWithdraw(_recipient, _amount);
_self.totalDeposited = _self.totalDeposited.sub(_decreasedValue);
return (_withdrawnAmount, _decreasedValue);
}
/// @dev Directly withdraw deposited funds from the vault.
///
/// @param _recipient the account to withdraw the tokens to.
/// @param _amount the amount of tokens to withdraw.
function directWithdraw(Data storage _self, address _recipient, uint256 _amount) internal returns (uint256, uint256) {
IDetailedERC20 _token = _self.token();
uint256 _startingBalance = _token.balanceOf(_recipient);
uint256 _startingTotalValue = _self.totalValue();
_self.adapter.withdraw(_recipient, _amount);
uint256 _endingBalance = _token.balanceOf(_recipient);
uint256 _withdrawnAmount = _endingBalance.sub(_startingBalance);
uint256 _endingTotalValue = _self.totalValue();
uint256 _decreasedValue = _startingTotalValue.sub(_endingTotalValue);
return (_withdrawnAmount, _decreasedValue);
}
/// @dev Withdraw all the deposited funds from the vault.
///
/// @param _recipient the account to withdraw the tokens to.
function withdrawAll(Data storage _self, address _recipient) internal returns (uint256, uint256) {
return _self.withdraw(_recipient, _self.totalDeposited);
}
/// @dev Harvests yield from the vault.
///
/// @param _recipient the account to withdraw the harvested yield to.
function harvest(Data storage _self, address _recipient) internal returns (uint256, uint256) {
if (_self.totalValue() <= _self.totalDeposited) {
return (0, 0);
}
uint256 _withdrawAmount = _self.totalValue().sub(_self.totalDeposited);
return _self.directWithdraw(_recipient, _withdrawAmount);
}
/// @dev Adds a element to the list.
///
/// @param _element the element to add.
function push(List storage _self, Data memory _element) internal {
_self.elements.push(_element);
}
/// @dev Gets a element from the list.
///
/// @param _index the index in the list.
///
/// @return the element at the specified index.
function get(List storage _self, uint256 _index) internal view returns (Data storage) {
return _self.elements[_index];
}
/// @dev Gets the last element in the list.
///
/// This function will revert if there are no elements in the list.
///
/// @return the last element in the list.
function last(List storage _self) internal view returns (Data storage) {
return _self.elements[_self.lastIndex()];
}
/// @dev Gets the index of the last element in the list.
///
/// This function will revert if there are no elements in the list.
///
/// @return the index of the last element.
function lastIndex(List storage _self) internal view returns (uint256) {
uint256 _length = _self.length();
return _length.sub(1, "Vault.List: empty");
}
/// @dev Gets the number of elements in the list.
///
/// @return the number of elements.
function length(List storage _self) internal view returns (uint256) {
return _self.elements.length;
}
}pragma solidity ^0.6.12;
interface IWETH9 {
event Approval(address indexed src, address indexed guy, uint wad);
event Transfer(address indexed src, address indexed dst, uint wad);
event Deposit(address indexed dst, uint wad);
event Withdrawal(address indexed src, uint wad);
function deposit() external payable;
function withdraw(uint wad) external;
function totalSupply() external view returns (uint);
function approve(address guy, uint wad) external returns (bool);
function transfer(address dst, uint wad) external returns (bool);
function transferFrom(address src, address dst, uint wad) external returns (bool);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function balanceOf(address guy) external view returns (uint256);
}// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IDetailedERC20} from "./interfaces/IDetailedERC20.sol";
/// @title AlToken
///
/// @dev This is the contract for the Alchemix utillity token usd.
///
/// Initially, the contract deployer is given both the admin and minter role. This allows them to pre-mine tokens,
/// transfer admin to a timelock contract, and lastly, grant the staking pools the minter role. After this is done,
/// the deployer must revoke their admin role and minter role.
contract AlEth is AccessControl, ERC20("Alchemix ETH", "alETH") {
using SafeERC20 for ERC20;
/// @dev The identifier of the role which maintains other roles.
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN");
/// @dev The identifier of the role which allows accounts to mint tokens.
bytes32 public constant SENTINEL_ROLE = keccak256("SENTINEL");
/// @dev addresses whitelisted for minting new tokens
mapping (address => bool) public whiteList;
/// @dev addresses paused for minting new tokens
mapping (address => bool) public paused;
/// @dev ceiling per address for minting new tokens
mapping (address => uint256) public ceiling;
/// @dev already minted amount per address to track the ceiling
mapping (address => uint256) public hasMinted;
event AlchemistPaused(address alchemistAddress, bool isPaused);
constructor() public {
_setupRole(ADMIN_ROLE, msg.sender);
_setupRole(SENTINEL_ROLE, msg.sender);
_setRoleAdmin(SENTINEL_ROLE,ADMIN_ROLE);
_setRoleAdmin(ADMIN_ROLE,ADMIN_ROLE);
}
/// @dev A modifier which checks if whitelisted for minting.
modifier onlyWhitelisted() {
require(whiteList[msg.sender], "AlETH: Alchemist is not whitelisted");
_;
}
/// @dev Mints tokens to a recipient.
///
/// This function reverts if the caller does not have the minter role.
///
/// @param _recipient the account to mint tokens to.
/// @param _amount the amount of tokens to mint.
function mint(address _recipient, uint256 _amount) external onlyWhitelisted {
require(!paused[msg.sender], "AlETH: Alchemist is currently paused.");
hasMinted[msg.sender] = hasMinted[msg.sender].add(_amount);
_mint(_recipient, _amount);
}
/// This function reverts if the caller does not have the admin role.
///
/// @param _toWhitelist the account to mint tokens to.
/// @param _state the whitelist state.
function setWhitelist(address _toWhitelist, bool _state) external onlyAdmin {
whiteList[_toWhitelist] = _state;
}
/// This function reverts if the caller does not have the admin role.
///
/// @param _newSentinel the account to set as sentinel.
function setSentinel(address _newSentinel) external onlyAdmin {
_setupRole(SENTINEL_ROLE, _newSentinel);
}
/// This function reverts if the caller does not have the sentinel role.
function pauseAlchemist(address _toPause, bool _state) external onlySentinel {
paused[_toPause] = _state;
AlchemistPaused(_toPause, _state);
}
/// This function reverts if the caller does not have the admin role.
///
/// @param _toSetCeiling the account set the ceiling off.
/// @param _ceiling the max amount of tokens the account is allowed to mint.
function setCeiling(address _toSetCeiling, uint256 _ceiling) external onlyAdmin {
ceiling[_toSetCeiling] = _ceiling;
}
/// @dev A modifier which checks that the caller has the admin role.
modifier onlyAdmin() {
require(hasRole(ADMIN_ROLE, msg.sender), "only admin");
_;
}
/// @dev A modifier which checks that the caller has the sentinel role.
modifier onlySentinel() {
require(hasRole(SENTINEL_ROLE, msg.sender), "only sentinel");
_;
}
/**
* @dev Destroys `amount` tokens from the caller.
*
* See {ERC20-_burn}.
*/
function burn(uint256 amount) public virtual {
_burn(_msgSender(), amount);
}
/**
* @dev Destroys `amount` tokens from `account`, deducting from the caller's
* allowance.
*
* See {ERC20-_burn} and {ERC20-allowance}.
*
* Requirements:
*
* - the caller must have allowance for ``accounts``'s tokens of at least
* `amount`.
*/
function burnFrom(address account, uint256 amount) public virtual {
uint256 decreasedAllowance = allowance(account, _msgSender()).sub(amount, "ERC20: burn amount exceeds allowance");
_approve(account, _msgSender(), decreasedAllowance);
_burn(account, amount);
}
/**
* @dev lowers hasminted from the caller's allocation
*
*/
function lowerHasMinted(uint256 amount) public onlyWhitelisted {
if (amount >= hasMinted[msg.sender]) {
hasMinted[msg.sender] = 0;
} else {
hasMinted[msg.sender] = hasMinted[msg.sender].sub(amount);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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 `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount) external returns (bool);
/**
* @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);
}// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.12;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IDetailedERC20 is IERC20 {
function name() external returns (string memory);
function symbol() external returns (string memory);
function decimals() external returns (uint8);
}// SPDX-License-Identifier: MIT
pragma solidity >= 0.4.22 <0.9.0;
library console {
address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);
function _sendLogPayload(bytes memory payload) private view {
uint256 payloadLength = payload.length;
address consoleAddress = CONSOLE_ADDRESS;
assembly {
let payloadStart := add(payload, 32)
let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)
}
}
function log() internal view {
_sendLogPayload(abi.encodeWithSignature("log()"));
}
function logInt(int p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(int)", p0));
}
function logUint(uint p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint)", p0));
}
function logString(string memory p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function logBool(bool p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function logAddress(address p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function logBytes(bytes memory p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
}
function logBytes1(bytes1 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
}
function logBytes2(bytes2 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
}
function logBytes3(bytes3 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
}
function logBytes4(bytes4 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
}
function logBytes5(bytes5 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
}
function logBytes6(bytes6 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
}
function logBytes7(bytes7 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
}
function logBytes8(bytes8 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
}
function logBytes9(bytes9 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
}
function logBytes10(bytes10 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
}
function logBytes11(bytes11 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
}
function logBytes12(bytes12 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
}
function logBytes13(bytes13 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
}
function logBytes14(bytes14 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
}
function logBytes15(bytes15 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
}
function logBytes16(bytes16 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
}
function logBytes17(bytes17 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
}
function logBytes18(bytes18 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
}
function logBytes19(bytes19 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
}
function logBytes20(bytes20 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
}
function logBytes21(bytes21 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
}
function logBytes22(bytes22 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
}
function logBytes23(bytes23 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
}
function logBytes24(bytes24 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
}
function logBytes25(bytes25 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
}
function logBytes26(bytes26 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
}
function logBytes27(bytes27 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
}
function logBytes28(bytes28 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
}
function logBytes29(bytes29 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
}
function logBytes30(bytes30 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
}
function logBytes31(bytes31 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
}
function logBytes32(bytes32 p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
}
function log(uint p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint)", p0));
}
function log(string memory p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function log(bool p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function log(address p0) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function log(uint p0, uint p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1));
}
function log(uint p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1));
}
function log(uint p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1));
}
function log(uint p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1));
}
function log(string memory p0, uint p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1));
}
function log(string memory p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
}
function log(string memory p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
}
function log(string memory p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
}
function log(bool p0, uint p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1));
}
function log(bool p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
}
function log(bool p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
}
function log(bool p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
}
function log(address p0, uint p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1));
}
function log(address p0, string memory p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
}
function log(address p0, bool p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
}
function log(address p0, address p1) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
}
function log(uint p0, uint p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2));
}
function log(uint p0, uint p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2));
}
function log(uint p0, uint p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2));
}
function log(uint p0, uint p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2));
}
function log(uint p0, string memory p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2));
}
function log(uint p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2));
}
function log(uint p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2));
}
function log(uint p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2));
}
function log(uint p0, bool p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2));
}
function log(uint p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2));
}
function log(uint p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2));
}
function log(uint p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2));
}
function log(uint p0, address p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2));
}
function log(uint p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2));
}
function log(uint p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2));
}
function log(uint p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2));
}
function log(string memory p0, uint p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2));
}
function log(string memory p0, uint p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2));
}
function log(string memory p0, uint p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2));
}
function log(string memory p0, uint p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2));
}
function log(string memory p0, string memory p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2));
}
function log(string memory p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
}
function log(string memory p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
}
function log(string memory p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
}
function log(string memory p0, bool p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2));
}
function log(string memory p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
}
function log(string memory p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
}
function log(string memory p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
}
function log(string memory p0, address p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2));
}
function log(string memory p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
}
function log(string memory p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
}
function log(string memory p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
}
function log(bool p0, uint p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2));
}
function log(bool p0, uint p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2));
}
function log(bool p0, uint p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2));
}
function log(bool p0, uint p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2));
}
function log(bool p0, string memory p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2));
}
function log(bool p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
}
function log(bool p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
}
function log(bool p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
}
function log(bool p0, bool p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2));
}
function log(bool p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
}
function log(bool p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
}
function log(bool p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
}
function log(bool p0, address p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2));
}
function log(bool p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
}
function log(bool p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
}
function log(bool p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
}
function log(address p0, uint p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2));
}
function log(address p0, uint p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2));
}
function log(address p0, uint p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2));
}
function log(address p0, uint p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2));
}
function log(address p0, string memory p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2));
}
function log(address p0, string memory p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
}
function log(address p0, string memory p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
}
function log(address p0, string memory p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
}
function log(address p0, bool p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2));
}
function log(address p0, bool p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
}
function log(address p0, bool p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
}
function log(address p0, bool p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
}
function log(address p0, address p1, uint p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2));
}
function log(address p0, address p1, string memory p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
}
function log(address p0, address p1, bool p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
}
function log(address p0, address p1, address p2) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
}
function log(uint p0, uint p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3));
}
function log(uint p0, uint p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3));
}
function log(uint p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3));
}
function log(uint p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3));
}
function log(uint p0, address p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3));
}
function log(uint p0, address p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3));
}
function log(uint p0, address p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3));
}
function log(uint p0, address p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3));
}
function log(uint p0, address p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3));
}
function log(uint p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3));
}
function log(uint p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3));
}
function log(uint p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3));
}
function log(uint p0, address p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3));
}
function log(uint p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3));
}
function log(uint p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3));
}
function log(uint p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3));
}
function log(uint p0, address p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3));
}
function log(uint p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3));
}
function log(uint p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3));
}
function log(uint p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {
_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 view {
_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 view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, string memory p3) internal view {
_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 view {
_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 view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, string memory p3) internal view {
_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 view {
_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 view {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, string memory p3) internal view {
_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 view {
_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 view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, string memory p3) internal view {
_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 view {
_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 view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, string memory p3) internal view {
_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 view {
_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 view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
}
function log(address p0, uint p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3));
}
function log(address p0, uint p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3));
}
function log(address p0, uint p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3));
}
function log(address p0, uint p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3));
}
function log(address p0, uint p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3));
}
function log(address p0, uint p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3));
}
function log(address p0, uint p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3));
}
function log(address p0, uint p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3));
}
function log(address p0, uint p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3));
}
function log(address p0, uint p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3));
}
function log(address p0, uint p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, uint p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3));
}
function log(address p0, uint p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3));
}
function log(address p0, uint p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3));
}
function log(address p0, uint p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3));
}
function log(address p0, uint p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, string memory p3) internal view {
_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 view {
_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 view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, uint p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, string memory p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, bool p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, address p3) internal view {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../utils/EnumerableSet.sol";
import "../utils/Address.sol";
import "../utils/Context.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms.
*
* 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:
*
* ```
* 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}:
*
* ```
* 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.
*/
abstract contract AccessControl is Context {
using EnumerableSet for EnumerableSet.AddressSet;
using Address for address;
struct RoleData {
EnumerableSet.AddressSet members;
bytes32 adminRole;
}
mapping (bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @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 {_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) public view returns (bool) {
return _roles[role].members.contains(account);
}
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) public view returns (uint256) {
return _roles[role].members.length();
}
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(bytes32 role, uint256 index) public view returns (address) {
return _roles[role].members.at(index);
}
/**
* @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 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.
*/
function grantRole(bytes32 role, address account) public virtual {
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant");
_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.
*/
function revokeRole(bytes32 role, address account) public virtual {
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke");
_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 granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) public virtual {
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.
*
* [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}.
* ====
*/
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 {
emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);
_roles[role].adminRole = adminRole;
}
function _grantRole(bytes32 role, address account) private {
if (_roles[role].members.add(account)) {
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) private {
if (_roles[role].members.remove(account)) {
emit RoleRevoked(role, account, _msgSender());
}
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "../../utils/Context.sol";
import "./IERC20.sol";
import "../../math/SafeMath.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin guidelines: functions revert instead
* of 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 {
using SafeMath for uint256;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
uint8 private _decimals;
/**
* @dev Sets the values for {name} and {symbol}, initializes {decimals} with
* a default value of 18.
*
* To select a different value for {decimals}, use {_setupDecimals}.
*
* All three of these values are immutable: they can only be set once during
* construction.
*/
constructor (string memory name_, string memory symbol_) public {
_name = name_;
_symbol = symbol_;
_decimals = 18;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5,05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
* called.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual returns (uint8) {
return _decimals;
}
/**
* @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:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, 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}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), 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}.
*
* Requirements:
*
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for ``sender``'s tokens of at least
* `amount`.
*/
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
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) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(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) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
return true;
}
/**
* @dev Moves tokens `amount` from `sender` to `recipient`.
*
* This is 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:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, 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:
*
* - `to` 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 = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(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);
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(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 Sets {decimals} to a value other than the default one of 18.
*
* WARNING: This function should only be called from the constructor. Most
* applications that interact with token contracts will not expect
* {decimals} to ever change, and may work incorrectly if it does.
*/
function _setupDecimals(uint8 decimals_) internal virtual {
_decimals = decimals_;
}
/**
* @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 to 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 { }
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <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 () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = 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");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping (bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) { // Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
// When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
require(set._values.length > index, "EnumerableSet: index out of bounds");
return set._values[index];
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <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 GSN 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 payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}{
"optimizer": {
"enabled": true,
"runs": 999999
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IMintableERC20","name":"_token","type":"address"},{"internalType":"contract AlEth","name":"_xtoken","type":"address"},{"internalType":"address","name":"_governance","type":"address"},{"internalType":"address","name":"_sentinel","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IVaultAdapter","name":"adapter","type":"address"}],"name":"ActiveVaultUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"covertedAmount","type":"uint256"}],"name":"CollateralConverted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"limit","type":"uint256"}],"name":"CollateralizationLimitUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"ConversionPauseUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"EmergencyExitUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FundsFlushed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"withdrawnAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"decreasedValue","type":"uint256"}],"name":"FundsHarvested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"withdrawnAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"decreasedValue","type":"uint256"}],"name":"FundsRecalled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"governance","type":"address"}],"name":"GovernanceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"HarvestFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"accounts","type":"address[]"},{"indexed":false,"internalType":"bool[]","name":"flag","type":"bool[]"}],"name":"KeepersSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"mintedAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"syntheticAddress","type":"address"}],"name":"LoanMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pendingGovernance","type":"address"}],"name":"PendingGovernanceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"treasury","type":"address"}],"name":"RewardsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sentinel","type":"address"}],"name":"SentinelUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"requestedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"withdrawnAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"decreasedValue","type":"uint256"}],"name":"TokensLiquidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"parentAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"childAmount","type":"uint256"}],"name":"TokensRepaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"requestedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"withdrawnAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"decreasedValue","type":"uint256"}],"name":"TokensWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"transmuter","type":"address"}],"name":"TransmuterUpdated","type":"event"},{"inputs":[],"name":"MAXIMUM_COLLATERALIZATION_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINIMUM_COLLATERALIZATION_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERCENT_RESOLUTION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ZERO_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"adapters","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateralizationLimit","outputs":[{"components":[{"internalType":"uint256","name":"x","type":"uint256"}],"internalType":"struct FixedPointMath.FixedDecimal","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"asEth","type":"bool"}],"name":"convert","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"asEth","type":"bool"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"emergencyExit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flush","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flushActivator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getCdpLastDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getCdpTotalCredit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getCdpTotalDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getCdpTotalDeposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vaultId","type":"uint256"}],"name":"getVaultAdapter","outputs":[{"internalType":"contract IVaultAdapter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vaultId","type":"uint256"}],"name":"getVaultTotalDeposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vaultId","type":"uint256"}],"name":"harvest","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"harvestFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IVaultAdapter","name":"_adapter","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"keepers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"liquidate","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IVaultAdapter","name":"_adapter","type":"address"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pauseConvert","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGovernance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vaultId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"recall","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_vaultId","type":"uint256"}],"name":"recallAll","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverLostFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_collateralAmount","type":"uint256"},{"internalType":"uint256","name":"_syntheticAmount","type":"uint256"},{"internalType":"bool","name":"collateralAsEth","type":"bool"}],"name":"repay","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"rewards","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sentinel","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"setCollateralizationLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_emergencyExit","type":"bool"}],"name":"setEmergencyExit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_flushActivator","type":"uint256"}],"name":"setFlushActivator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_harvestFee","type":"uint256"}],"name":"setHarvestFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"bool[]","name":"flags","type":"bool[]"}],"name":"setKeepers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_pauseConvert","type":"bool"}],"name":"setPauseConvert","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pendingGovernance","type":"address"}],"name":"setPendingGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewards","type":"address"}],"name":"setRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sentinel","type":"address"}],"name":"setSentinel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_transmuter","type":"address"}],"name":"setTransmuter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IMintableERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDeposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"transmuter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"asEth","type":"bool"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"xtoken","outputs":[{"internalType":"contract AlEth","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60806040523480156200001157600080fd5b50604051620057cb380380620057cb8339810160408190526200003491620001b3565b60016000556001600160a01b0382166200006b5760405162461bcd60e51b815260040162000062906200021a565b60405180910390fd5b6001600160a01b038116620000945760405162461bcd60e51b81526004016200006290620002a7565b600280546001600160a01b03199081166001600160a01b0387811691821790935560018054831690911790556003805482168684161790556004805482168584161781556006805490921692841692909217905569021e19e0c9bab2400000600b55600c80546201000061010061ff00199092169190911762ff000019161790556000906200013990670de0b6b3a7640000906200016a602090811b62002ea717901c565b604080516020808201835290839052600d9290925580519182019052600090819052600e55506200030a9350505050565b6000826200017b57506000620001ad565b828202828482816200018957fe5b0414620001aa5760405162461bcd60e51b8152600401620000629062000266565b90505b92915050565b60008060008060808587031215620001c9578384fd5b8451620001d681620002f1565b6020860151909450620001e981620002f1565b6040860151909350620001fc81620002f1565b60608601519092506200020f81620002f1565b939692955090935050565b6020808252602c908201527f416c6368656d6973743a20676f7665726e616e6365206164647265737320636160408201526b373737ba10313290183c181760a11b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602a908201527f416c6368656d6973743a2073656e74696e656c20616464726573732063616e6e60408201526937ba10313290183c181760b11b606082015260800190565b6001600160a01b03811681146200030757600080fd5b50565b6154b1806200031a6000396000f3fe6080604052600436106103435760003560e01c8063792b55b6116101b0578063b5962917116100ec578063f0d787a311610095578063fc00e8a01161006f578063fc00e8a01461088e578063fc0c546a146108ae578063fefdc5d1146108c3578063ff50abdc146108e35761034a565b8063f0d787a31461084f578063f39c38a014610864578063f58c251c146108795761034a565b8063ddc63262116100c6578063ddc63262146107ef578063e5711ffc1461080f578063ec38a8621461082f5761034a565b8063b59629171461079a578063c4d66de8146107af578063ce5494bb146107cf5761034a565b8063a0712d6811610159578063a7c6a10011610133578063a7c6a10014610725578063aa6e04341461073a578063aaf166601461075a578063adb4a9ad1461077a5761034a565b8063a0712d68146106d0578063a1e401a9146106f0578063a59d6986146107105761034a565b80639a5ef3691161018a5780639a5ef369146106885780639a9af2211461069b5780639ec5a894146106bb5761034a565b8063792b55b61461063557806399da775b146106555780639a408321146106755761034a565b8063415f12401161027f57806353ffa18b116102285780636a4f4b05116102025780636a4f4b05146105d85780636b9f96ea146105f85780636fd522981461060d5780637239d2b9146106205761034a565b806353ffa18b1461058e5780635641ec03146105ae5780635aa6e675146105c35761034a565b80634aaf7c65116102595780634aaf7c65146105375780634c3a8e0214610559578063538ba4f9146105795761034a565b8063415f1240146104e257806345ee07551461050257806345f867b3146105225761034a565b8063238efcbc116102ec57806338d07436116102c657806338d074361461046a5780633bbd64bc146104985780633fc8cef3146104b8578063411d6fb5146104cd5761034a565b8063238efcbc146104205780632670fdd81461043557806330d4d190146104555761034a565b8063158ef93e1161031d578063158ef93e146103bc5780631718a68f146103de57806322c37b75146104005761034a565b80630510111e1461034f57806309dac0611461037a5780630abb60351461039c5761034a565b3661034a57005b600080fd5b34801561035b57600080fd5b506103646108f8565b6040516103719190615376565b60405180910390f35b34801561038657600080fd5b5061039a6103953660046145fb565b610904565b005b3480156103a857600080fd5b5061039a6103b73660046145fb565b610a26565b3480156103c857600080fd5b506103d1610b34565b60405161037191906148d0565b3480156103ea57600080fd5b506103f3610b3d565b60405161037191906147b2565b34801561040c57600080fd5b5061039a61041b3660046146d4565b610b59565b34801561042c57600080fd5b5061039a610baf565b34801561044157600080fd5b506103f36104503660046146d4565b610c76565b34801561046157600080fd5b50610364610ca2565b34801561047657600080fd5b5061048a610485366004614704565b610cae565b6040516103719291906153a3565b3480156104a457600080fd5b506103d16104b33660046145fb565b610eb3565b3480156104c457600080fd5b506103f3610ec8565b3480156104d957600080fd5b506103d1610ee4565b3480156104ee57600080fd5b5061048a6104fd3660046146d4565b610ef3565b34801561050e57600080fd5b5061039a61051d366004614680565b611099565b34801561052e57600080fd5b5061036461116c565b34801561054357600080fd5b5061054c611172565b604051610371919061536c565b34801561056557600080fd5b5061048a6105743660046146d4565b61118e565b34801561058557600080fd5b506103f361123c565b34801561059a57600080fd5b5061039a6105a93660046146d4565b611241565b3480156105ba57600080fd5b506103d1611356565b3480156105cf57600080fd5b506103f3611364565b3480156105e457600080fd5b5061039a6105f3366004614617565b611380565b34801561060457600080fd5b506103646114c3565b61039a61061b366004614754565b6115e0565b34801561062c57600080fd5b506103f3611997565b34801561064157600080fd5b5061039a6106503660046146d4565b6119b3565b34801561066157600080fd5b5061039a610670366004614680565b611a75565b61039a610683366004614704565b611b49565b61039a610696366004614704565b611e0d565b3480156106a757600080fd5b506103646106b63660046145fb565b612296565b3480156106c757600080fd5b506103f36122c1565b3480156106dc57600080fd5b5061039a6106eb3660046146d4565b6122dd565b3480156106fc57600080fd5b5061036461070b3660046145fb565b612690565b34801561071c57600080fd5b5061039a6126b8565b34801561073157600080fd5b50610364612752565b34801561074657600080fd5b506103646107553660046145fb565b612763565b34801561076657600080fd5b506103646107753660046146d4565b61279a565b34801561078657600080fd5b5061039a6107953660046145fb565b6127b3565b3480156107a657600080fd5b506103646128c1565b3480156107bb57600080fd5b5061039a6107ca3660046145fb565b6128c7565b3480156107db57600080fd5b5061039a6107ea3660046145fb565b612a2a565b3480156107fb57600080fd5b5061048a61080a3660046146d4565b612ac0565b34801561081b57600080fd5b506103d161082a3660046145fb565b612c69565b34801561083b57600080fd5b5061039a61084a3660046145fb565b612c7e565b34801561085b57600080fd5b50610364612d8c565b34801561087057600080fd5b506103f3612d92565b34801561088557600080fd5b506103f3612dae565b34801561089a57600080fd5b506103646108a93660046145fb565b612dca565b3480156108ba57600080fd5b506103f3612dfa565b3480156108cf57600080fd5b5061048a6108de366004614733565b612e16565b3480156108ef57600080fd5b50610364612ea1565b673782dace9d90000081565b60045473ffffffffffffffffffffffffffffffffffffffff16331461095e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166109ab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610955906151e7565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790556040517fdc117600f93282860144d2cd2745f8e2e15c3ca2a32b4290c30f7cd1ae7ffcb990610a1b9083906147b2565b60405180910390a150565b60045473ffffffffffffffffffffffffffffffffffffffff163314610a77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b73ffffffffffffffffffffffffffffffffffffffff8116610ac4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614989565b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790556040517fc9e2377236eab4280090ce8f2317332649736d92f00dcf20a8dd6684ec5e783990610a1b9083906147b2565b600c5460ff1681565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b60045473ffffffffffffffffffffffffffffffffffffffff163314610baa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b600b55565b60055473ffffffffffffffffffffffffffffffffffffffff163314610c00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614ef2565b600554600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691821790556040517f9d3e522e1e47a2f6009739342b9cc7b252a1888154e843ab55ee1c81745795ab90610a1b9083906147b2565b600080610c84601184612f04565b5473ffffffffffffffffffffffffffffffffffffffff169392505050565b670de0b6b3a764000081565b60008060026000541415610cee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b6002600055610cfc33612f2b565b158015610d0857503332145b610d3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b0e565b600c5460ff16610d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b336000908152600f6020526040902060038101544311610dc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614fbd565b610dd181600d612f31565b600080610ddf338888612f8d565b60408051808201909152601b81527f4578636565647320776974686472617761626c6520616d6f756e74000000000060208201528554929450909250610e27919083906132b5565b835560408051606081019091526031808252610e5091600d9161542460208301398591906132fb565b3373ffffffffffffffffffffffffffffffffffffffff167fb3ad69dc1d2c6b1f5f5b0927ffd8ee8f1437a156253c8f6dccc75e6f8e4fd38b888484604051610e9a939291906153b1565b60405180910390a2600160005590969095509350505050565b60126020526000908152604090205460ff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b600c5462010000900460ff1681565b60008060026000541415610f33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b6002600055610f4133612f2b565b158015610f4d57503332145b610f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b0e565b600c5460ff16610fbf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b336000908152600f60205260409020610fd981600d612f31565b8060010154841115610fed57806001015493505b600080610ffc30876000612f8d565b9150915061100982613344565b60408051602081019091526000815283546110259183906132b5565b835560408051602081019091526000815260018401546110469184906132b5565b600184015560405133907f3ea051727656be6fd11c2260f244f29ff3c70d1fb077bfa73e89d554e9bb95c790611081908990869086906153b1565b60405180910390a26001600055909590945092505050565b60045473ffffffffffffffffffffffffffffffffffffffff163314806110d6575060065473ffffffffffffffffffffffffffffffffffffffff1633145b61110c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614f29565b600c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100831515021790556040517ff0064f2efd0da4bc63eecf2e75590fe8a308eaa526a51c334e50eec09a71104990610a1b9083906148d0565b61271081565b61117a61459b565b506040805160208101909152600d54815290565b600080600260005414156111ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b6002600055600c5460ff1661120f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b600061121c601185612f04565b905061122c848260010154613508565b6001600055909590945092505050565b600081565b60045473ffffffffffffffffffffffffffffffffffffffff163314611292576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b670de0b6b3a76400008110156112d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614c7c565b673782dace9d900000811115611316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614cd9565b60408051602081018252829052600d829055517ff78180bc708b1292177c888900951cd66a39faf48dc7b6d111e93285dbbe55a090610a1b908390615376565b600c54610100900460ff1681565b60045473ffffffffffffffffffffffffffffffffffffffff1681565b60045473ffffffffffffffffffffffffffffffffffffffff1633146113d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b8260005b8181101561147e578383828181106113e957fe5b90506020020160208101906113fe9190614680565b6012600088888581811061140e57fe5b905060200201602081019061142391906145fb565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556001016113d5565b507fd1721b10ac5fe95d2627d512aa0f92c34ada0347c874adf414cf51af5760ff56858585856040516114b4949392919061482a565b60405180910390a15050505050565b600060026000541415611502576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b6002600055600c5460ff16611543576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b3360009081526012602052604090205460ff1661158c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614ad7565b600c54610100900460ff16156115ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614fce565b6115d66135ed565b9050600160005590565b6002600054141561161d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b600260005561162b33612f2b565b15801561163757503332145b61166d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b0e565b600c5460ff166116a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b8015806116bc57508080156116bc575082155b80156116c757503415155b156116fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d36565b336000908152600f6020526040902061171881600d612f31565b83156118135781156117e55734841461175d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061511c565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b1580156117c757600080fd5b505af11580156117db573d6000803e3d6000fd5b505050505061180a565b60015461180a9073ffffffffffffffffffffffffffffffffffffffff16333087613646565b61181384613344565b821561192c576003546040517f79cc679000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906379cc67909061187190339087906004016147d3565b600060405180830381600087803b15801561188b57600080fd5b505af115801561189f573d6000803e3d6000fd5b50506003546040517f288aafcb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116925063288aafcb91506118f9908690600401615376565b600060405180830381600087803b15801561191357600080fd5b505af1158015611927573d6000803e3d6000fd5b505050505b600061193885856136e9565b600183015490915061194a9082613728565b600183015560405133907fbade234341a40ca3c71df59b3ca02b8bb65b491a098af970953228b4f4a5d38f9061198390889088906153a3565b60405180910390a250506001600055505050565b60075473ffffffffffffffffffffffffffffffffffffffff1681565b60045473ffffffffffffffffffffffffffffffffffffffff163314611a04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b612710811115611a40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614e95565b60098190556040517fc36862a253ff42cc71f4f200d3c62e8e5eaaece01041fc6900aeace64ade72a890610a1b908390615376565b60045473ffffffffffffffffffffffffffffffffffffffff16331480611ab2575060065473ffffffffffffffffffffffffffffffffffffffff1633145b611ae8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614f29565b600c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff1662010000831515021790556040517fca5bdce9cd3e7e41a11035b530ba304b2e5d57e39872a18c079cb3fb7a48b6c290610a1b9083906148d0565b60026000541415611b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b6002600055611b9433612f2b565b158015611ba057503332145b611bd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b0e565b600c5460ff16611c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b600c54610100900460ff1615611c54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614fce565b336000908152600f60205260409020611c6e81600d612f31565b8115611d3557348314611cad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061503c565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0846040518263ffffffff1660e01b81526004016000604051808303818588803b158015611d1757600080fd5b505af1158015611d2b573d6000803e3d6000fd5b5050505050611d92565b3415611d6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b7a565b600154611d929073ffffffffffffffffffffffffffffffffffffffff16333086613646565b600b548310611da557611da36135ed565b505b600a54611db290846136e9565b600a558054611dc190846136e9565b815543600382015560405133907f59062170a285eb80e8c6b8ced60428442a51910635005233fc4ce084a475845e90611dfb908690615376565b60405180910390a25050600160005550565b60026000541415611e4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b6002600055611e5833612f2b565b158015611e6457503332145b611e9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b0e565b600c5460ff16611ed6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b600c5462010000900460ff1615611f19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614ddb565b8015611fe057348214611f58576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061503c565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b158015611fc257600080fd5b505af1158015611fd6573d6000803e3d6000fd5b505050505061203d565b3415612018576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b7a565b60015461203d9073ffffffffffffffffffffffffffffffffffffffff16333085613646565b6003546040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906340c10f199061209590339086906004016147d3565b600060405180830381600087803b1580156120af57600080fd5b505af11580156120c3573d6000803e3d6000fd5b505050506120d082613344565b6003546040517f1ac997e000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690631ac997e0906121269030906004016147b2565b60206040518083038186803b15801561213e57600080fd5b505afa158015612152573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217691906146ec565b6003546040517f38e21cce00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906338e21cce906121cc9030906004016147b2565b60206040518083038186803b1580156121e457600080fd5b505afa1580156121f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221c91906146ec565b1115612254576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614f60565b7fda3499e7f2a8b7272740278bd7e34f34f8643fd2dac543aeb2b2df98a2bedb5f33836040516122859291906147d3565b60405180910390a150506001600055565b73ffffffffffffffffffffffffffffffffffffffff166000908152600f602052604090206003015490565b60085473ffffffffffffffffffffffffffffffffffffffff1681565b6002600054141561231a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b600260005561232833612f2b565b15801561233457503332145b61236a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b0e565b600c5460ff166123a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b336000908152600f602052604090206123c081600d612f31565b6002810154828110156124245760006123d98483613728565b60018401549091506123eb90826136e9565b6001840155600060028401556040805160608101909152602780825261241e91600d9161545560208301398591906132fb565b50612434565b61242e8184613728565b60028301555b6003546040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906340c10f199061248c90339087906004016147d3565b600060405180830381600087803b1580156124a657600080fd5b505af11580156124ba573d6000803e3d6000fd5b50506003546040517f1ac997e000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169250631ac997e091506125149030906004016147b2565b60206040518083038186803b15801561252c57600080fd5b505afa158015612540573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256491906146ec565b6003546040517f38e21cce00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906338e21cce906125ba9030906004016147b2565b60206040518083038186803b1580156125d257600080fd5b505afa1580156125e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260a91906146ec565b1115612642576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614f60565b60035460405133917f85334969bebc6a94eec30db9687223c52b4a36180ca90c27e42efa05a9202c7491611dfb91879173ffffffffffffffffffffffffffffffffffffffff9091169061537f565b73ffffffffffffffffffffffffffffffffffffffff166000908152600f602052604090205490565b60045473ffffffffffffffffffffffffffffffffffffffff163314612709576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b60045460405173ffffffffffffffffffffffffffffffffffffffff909116904780156108fc02916000818181858888f1935050505015801561274f573d6000803e3d6000fd5b50565b600061275e601161376a565b905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600f6020526040812061279381600d61376e565b9392505050565b6000806127a8601184612f04565b600101549392505050565b60045473ffffffffffffffffffffffffffffffffffffffff163314612804576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b73ffffffffffffffffffffffffffffffffffffffff8116612851576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061492c565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790556040517fe42bb1780117f5788c6e0042e955291223819875891ddf465b8e4fbb85a933e990610a1b9083906147b2565b60095481565b60045473ffffffffffffffffffffffffffffffffffffffff163314612918576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b600c5460ff1615612955576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b43565b60075473ffffffffffffffffffffffffffffffffffffffff166129a4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610955906149e6565b60085473ffffffffffffffffffffffffffffffffffffffff166129f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614a7a565b6129fc816137ad565b50600c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600c5460ff16612a66576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b60045473ffffffffffffffffffffffffffffffffffffffff163314612ab7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b61274f816137ad565b600c54600090819060ff16612b01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b3360009081526012602052604090205460ff16612b4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614ad7565b6000612b57601185612f04565b9050600080612b6683306139fb565b90925090508115612c25576000612b94612710612b8e60095486612ea790919063ffffffff16565b90613a4e565b90506000612ba28483613728565b9050612bac61459b565b612bc1600a54612bbb84613a9a565b90613adc565b6040805160208101909152600e548152909150612bde9082613b10565b51600e558215612c1257600854600154612c129173ffffffffffffffffffffffffffffffffffffffff918216911685613b40565b8115612c2157612c2182613344565b5050505b7f11d2034f4471d11a13f0f1798ceaf0c9db2812d450a0681958ce7d4f2fb97f098282604051612c569291906153a3565b60405180910390a1909350915050915091565b60106020526000908152604090205460ff1681565b60045473ffffffffffffffffffffffffffffffffffffffff163314612ccf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b73ffffffffffffffffffffffffffffffffffffffff8116612d1c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061530f565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790556040517f05f3326e0527f309d4015dee3bc3f36e650b53fc823bab69c99847814acfafdf90610a1b9083906147b2565b600b5481565b60055473ffffffffffffffffffffffffffffffffffffffff1681565b60065473ffffffffffffffffffffffffffffffffffffffff1681565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600f6020526040812061279381600d613b64565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b60008060026000541415612e56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b6002600055600c5460ff16612e97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b61122c8484613508565b600a5481565b600082612eb657506000612efe565b82820282848281612ec357fe5b0414612efb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614e38565b90505b92915050565b6000826000018281548110612f1557fe5b9060005260206000209060020201905092915050565b3b151590565b6000612f3d8383613bab565b90508260010154811115612f6b576001830180546000909155612f608282613728565b600285015550612f80565b6001830154612f7a9082613728565b60018401555b5060010154600490910155565b6001546040517f70a082310000000000000000000000000000000000000000000000000000000081526000918291829161304391879173ffffffffffffffffffffffffffffffffffffffff16906370a0823190612fee9030906004016147b2565b60206040518083038186803b15801561300657600080fd5b505afa15801561301a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061303e91906146ec565b613c24565b905073ffffffffffffffffffffffffffffffffffffffff8616301461315d578315613139576002546040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d906130be908490600401615376565b600060405180830381600087803b1580156130d857600080fd5b505af11580156130ec573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff8916925083156108fc02915083906000818181858888f19350505050158015613133573d6000803e3d6000fd5b5061315d565b60015461315d9073ffffffffffffffffffffffffffffffffffffffff168783613b40565b8080600061316b8883613728565b9050801561329757600061317f6011613c3a565b9050600080891561326a57613195833086613c65565b6002546040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815292945090925073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d906131ef908590600401615376565b600060405180830381600087803b15801561320957600080fd5b505af115801561321d573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff8f16925084156108fc02915084906000818181858888f19350505050158015613264573d6000803e3d6000fd5b5061327b565b613275838d86613c65565b90925090505b61328586836136e9565b955061329185826136e9565b94505050505b600a546132a49083613728565b600a55509097909650945050505050565b600081848411156132f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095591906148db565b505050900390565b6133058383613c9b565b819061333e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095591906148db565b50505050565b6001546007546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169263095ea7b3926133a09291169085906004016147d3565b602060405180830381600087803b1580156133ba57600080fd5b505af11580156133ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133f2919061469c565b506007546040517ffb93210800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063fb9321089061344b90309085906004016147d3565b600060405180830381600087803b15801561346557600080fd5b505af1158015613479573d6000803e3d6000fd5b50506003546040517f288aafcb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116925063288aafcb91506134d3908490600401615376565b600060405180830381600087803b1580156134ed57600080fd5b505af1158015613501573d6000803e3d6000fd5b5050505050565b600c546000908190610100900460ff168061353a575060045473ffffffffffffffffffffffffffffffffffffffff1633145b8061354e575061354a6011613cc9565b8414155b613584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615073565b6000613591601186612f04565b90506000806135a1833088613c65565b91509150867fccbd929f935422b28ee209a0db0556280b0a3d9bc4da58f1d3f0ab4f8a49964783836040516135d79291906153a3565b60405180910390a29093509150505b9250929050565b6000806135fa6011613c3a565b9050600061360782613d22565b90507f860f4701faa0ecdeecd9e9eaae11a8612bbd01c663081f7c0c4e4873df653d69816040516136389190615376565b60405180910390a191505090565b61333e846323b872dd60e01b858585604051602401613667939291906147f9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613dc3565b600082820183811015612efb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614a43565b600082821115613764576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614bb1565b50900390565b5490565b60008061377b8484613bab565b90508061378e5750506001820154612efe565b60018401548082106137a557600092505050612efe565b039392505050565b73ffffffffffffffffffffffffffffffffffffffff81166137fa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610955906152b2565b600154604080517ffc0c546a000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9283169284169163fc0c546a916004808301926020929190829003018186803b15801561386757600080fd5b505afa15801561387b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061389f91906146b8565b73ffffffffffffffffffffffffffffffffffffffff16146138ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061527b565b73ffffffffffffffffffffffffffffffffffffffff811660009081526010602052604090205460ff161561394c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614da4565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260106020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580518082019091529283528201526139b790601190613e79565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f0821015de34e20b0878a40f6f165801417f53b2017016d7321cacee989c8cfa790600090a250565b6000808360010154613a0c85613ee1565b11613a1c575060009050806135e6565b6000613a358560010154613a2f87613ee1565b90613728565b9050613a42858583613f83565b92509250509250929050565b6000808211613a89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614c45565b818381613a9257fe5b049392505050565b613aa261459b565b6000821580613abf575050670de0b6b3a764000082810290810483145b613ac857600080fd5b604080516020810190915290815292915050565b613ae461459b565b81613aee57600080fd5b604051806020016040528083856000015181613b0657fe5b0490529392505050565b613b1861459b565b82518251810190811015613b2b57600080fd5b60408051602081019091529081529392505050565b613b5f8363a9059cbb60e01b84846040516024016136679291906147d3565b505050565b600080613b718484613bab565b905080613b845750506002820154612efe565b6001840154808211613b9b57600092505050612efe565b6002850154910301905092915050565b6000613bb561459b565b50604080516020810190915260018301548152613bd061459b565b50604080516020810190915260048501548152613bed8282614196565b613bfc57600092505050612efe565b8454613c1b90613c1690613c1085856141e5565b90614200565b61422e565b95945050505050565b6000818310613c335781612efb565b5090919050565b600081613c4681613cc9565b81548110613c5057fe5b90600052602060002090600202019050919050565b6000808080613c75878787613f83565b60018901549193509150613c899082613728565b60018801559092509050935093915050565b600080613cc0613cab858561423d565b60408051602081019091528554815290614196565b13159392505050565b600080613cd58361376a565b905061279360016040518060400160405280601181526020017f5661756c742e4c6973743a20656d707479000000000000000000000000000000815250836132b59092919063ffffffff16565b600080613d2e83614281565b90506127938173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401613d6c91906147b2565b60206040518083038186803b158015613d8457600080fd5b505afa158015613d98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dbc91906146ec565b8490614323565b6060613e25826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166143fd9092919063ffffffff16565b805190915015613b5f5780806020019051810190613e43919061469c565b613b5f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061518a565b8154600180820184556000938452602093849020835160029093020180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921782559190920151910155565b8054604080517fd4c3eea0000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163d4c3eea0916004808301926020929190829003018186803b158015613f4b57600080fd5b505afa158015613f5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612efe91906146ec565b6000806000613f9186614281565b905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231876040518263ffffffff1660e01b8152600401613fce91906147b2565b60206040518083038186803b158015613fe657600080fd5b505afa158015613ffa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061401e91906146ec565b9050600061402b88613ee1565b88546040517ff3fef3a300000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff169063f3fef3a390614083908a908a906004016147d3565b600060405180830381600087803b15801561409d57600080fd5b505af11580156140b1573d6000803e3d6000fd5b50506040517f70a082310000000000000000000000000000000000000000000000000000000081526000925073ffffffffffffffffffffffffffffffffffffffff861691506370a082319061410a908b906004016147b2565b60206040518083038186803b15801561412257600080fd5b505afa158015614136573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061415a91906146ec565b905060006141688285613728565b905060006141758b613ee1565b905060006141838583613728565b929c929b50919950505050505050505050565b8051825160009111156141ca57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612efe565b8151835111156141dc57506001612efe565b50600092915050565b6141ed61459b565b82518251810390811115613b2b57600080fd5b61420861459b565b600082158061422557505082518281029083828161422257fe5b04145b613b2b57600080fd5b51670de0b6b3a7640000900490565b61424561459b565b6000614251848461376e565b9050806142685761426061440c565b915050612efe565b61427981612bbb8660000154613a9a565b949350505050565b8054604080517ffc0c546a000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163fc0c546a916004808301926020929190829003018186803b1580156142eb57600080fd5b505afa1580156142ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612efe91906146b8565b60008061432f84614281565b84549091506143589073ffffffffffffffffffffffffffffffffffffffff808416911685613b40565b83546040517fb6b55f2500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063b6b55f25906143ad908690600401615376565b600060405180830381600087803b1580156143c757600080fd5b505af11580156143db573d6000803e3d6000fd5b50505060018501546143ee9150846136e9565b60018501555081905092915050565b60606142798484600085614446565b61441461459b565b5060408051602081019091527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff815290565b606082471015614482576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614be8565b61448b85612f2b565b6144c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615005565b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040516144eb9190614796565b60006040518083038185875af1925050503d8060008114614528576040519150601f19603f3d011682016040523d82523d6000602084013e61452d565b606091505b509150915061453d828286614548565b979650505050505050565b60608315614557575081612793565b8251156145675782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095591906148db565b6040518060200160405280600081525090565b60008083601f8401126145bf578182fd5b50813567ffffffffffffffff8111156145d6578182fd5b60208301915083602080830285010111156135e657600080fd5b8035612efe81615415565b60006020828403121561460c578081fd5b8135612efb816153f3565b6000806000806040858703121561462c578283fd5b843567ffffffffffffffff80821115614643578485fd5b61464f888389016145ae565b90965094506020870135915080821115614667578384fd5b50614674878288016145ae565b95989497509550505050565b600060208284031215614691578081fd5b8135612efb81615415565b6000602082840312156146ad578081fd5b8151612efb81615415565b6000602082840312156146c9578081fd5b8151612efb816153f3565b6000602082840312156146e5578081fd5b5035919050565b6000602082840312156146fd578081fd5b5051919050565b60008060408385031215614716578182fd5b82359150602083013561472881615415565b809150509250929050565b60008060408385031215614745578182fd5b50508035926020909101359150565b600080600060608486031215614768578283fd5b8335925060208401359150604084013561478181615415565b809150509250925092565b1515815260200190565b600082516147a88184602087016153c7565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff9384168152919092166020820152604081019190915260600190565b6040808252810184905260008560608301825b8781101561487a5760208335614852816153f3565b73ffffffffffffffffffffffffffffffffffffffff168352928301929091019060010161483d565b506020915083810382850152806148918683615376565b9050869150835b868110156148c3578383016148b6836148b183876145f0565b61478c565b9093509150600101614898565b5098975050505050505050565b901515815260200190565b60006020825282518060208401526148fa8160408501602087016153c7565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6020808252602c908201527f416c6368656d6973743a207472616e736d75746572206164647265737320636160408201527f6e6e6f74206265203078302e0000000000000000000000000000000000000000606082015260800190565b6020808252602c908201527f416c6368656d6973743a20676f7665726e616e6365206164647265737320636160408201527f6e6e6f74206265203078302e0000000000000000000000000000000000000000606082015260800190565b60208082526036908201527f416c6368656d6973743a2063616e6e6f7420696e697469616c697a652074726160408201527f6e736d75746572206164647265737320746f2030783000000000000000000000606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526033908201527f416c6368656d6973743a2063616e6e6f7420696e697469616c697a652072657760408201527f61726473206164647265737320746f2030783000000000000000000000000000606082015260800190565b60208082526018908201527f416c6368656d6973743a206f6e6c79206b6565706572732e0000000000000000604082015260600190565b6020808252818101527f536f72727920776520646f206e6f742061636365707420636f6e747261637421604082015260600190565b6020808252601e908201527f416c6368656d6973743a20616c726561647920696e697469616c697a65640000604082015260600190565b6020808252600e908201527f6d73672e76616c756520213d2030000000000000000000000000000000000000604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60408201527f722063616c6c0000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b60208082526031908201527f416c6368656d6973743a20636f6c6c61746572616c697a6174696f6e206c696d60408201527f69742062656c6f77206d696e696d756d2e000000000000000000000000000000606082015260800190565b60208082526031908201527f416c6368656d6973743a20636f6c6c61746572616c697a6174696f6e206c696d60408201527f69742061626f7665206d6178696d756d2e000000000000000000000000000000606082015260800190565b6020808252600d908201527f626c61636b686f6c652045544800000000000000000000000000000000000000604082015260600190565b6020808252601b908201527f416c6368656d6973743a206f6e6c7920676f7665726e616e63652e0000000000604082015260600190565b60208082526016908201527f4164617074657220616c726561647920696e2075736500000000000000000000604082015260600190565b60208082526022908201527f416c6368656d6973743a20636f6e76657273696f6e732061726520706175736560408201527f642e000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60408201527f7700000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526025908201527f416c6368656d6973743a2068617276657374206665652061626f7665206d617860408201527f696d756d2e000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601f908201527f73656e646572206973206e6f742070656e64696e67476f7665726e616e636500604082015260600190565b60208082526018908201527f21676f7665726e616e6365202626202173656e74696e656c0000000000000000604082015260600190565b60208082526028908201527f416c4554483a20416c6368656d6973742773206365696c696e6720776173206260408201527f726561636865642e000000000000000000000000000000000000000000000000606082015260800190565b602080825260009082015260400190565b60208082526017908201527f656d657267656e637920706175736520656e61626c6564000000000000000000604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b60208082526014908201527f5f616d6f756e7420213d206d73672e76616c7565000000000000000000000000604082015260600190565b60208082526070908201527f416c6368656d6973743a206e6f7420616e20656d657267656e63792c206e6f7460408201527f20676f7665726e616e63652c20616e64207573657220646f6573206e6f74206860608201527f617665207065726d697373696f6e20746f20726563616c6c2066756e6473206660808201527f726f6d20616374697665207661756c740000000000000000000000000000000060a082015260c00190565b6020808252601e908201527f5f636f6c6c61746572616c416d6f756e7420213d206d73672e76616c75650000604082015260600190565b6020808252601b908201527f416c6368656d6973743a206e6f7420696e697469616c697a65642e0000000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60408201527f6f74207375636365656400000000000000000000000000000000000000000000606082015260800190565b6020808252602a908201527f416c6368656d6973743a2073656e74696e656c20616464726573732063616e6e60408201527f6f74206265203078302e00000000000000000000000000000000000000000000606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252601a908201527f416c6368656d6973743a20746f6b656e206d69736d617463682e000000000000604082015260600190565b6020808252602e908201527f416c6368656d6973743a20616374697665207661756c7420616464726573732060408201527f63616e6e6f74206265203078302e000000000000000000000000000000000000606082015260800190565b60208082526029908201527f416c6368656d6973743a207265776172647320616464726573732063616e6e6f60408201527f74206265203078302e0000000000000000000000000000000000000000000000606082015260800190565b9051815260200190565b90815260200190565b91825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b918252602082015260400190565b9283526020830191909152604082015260600190565b60005b838110156153e25781810151838201526020016153ca565b8381111561333e5750506000910152565b73ffffffffffffffffffffffffffffffffffffffff8116811461274f57600080fd5b801515811461274f57600080fdfe416374696f6e20626c6f636b65643a20756e6865616c74687920636f6c6c61746572616c697a6174696f6e20726174696f416c6368656d6973743a204c6f616e2d746f2d76616c756520726174696f206272656163686564a2646970667358221220ac606f4f47d6a62065e11f2374342d0890a2149715b9b0dc8a108852fdc6cb1764736f6c634300060c0033000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000100546f2cd4c9d97f798ffc9755e47865ff7ee60000000000000000000000000e78588283aa9ccbec277b40fb8edfa8cc2155a7000000000000000000000000f4b5b84b8f39bc556ed230fa91a0a89bb5e8559b
Deployed Bytecode
0x6080604052600436106103435760003560e01c8063792b55b6116101b0578063b5962917116100ec578063f0d787a311610095578063fc00e8a01161006f578063fc00e8a01461088e578063fc0c546a146108ae578063fefdc5d1146108c3578063ff50abdc146108e35761034a565b8063f0d787a31461084f578063f39c38a014610864578063f58c251c146108795761034a565b8063ddc63262116100c6578063ddc63262146107ef578063e5711ffc1461080f578063ec38a8621461082f5761034a565b8063b59629171461079a578063c4d66de8146107af578063ce5494bb146107cf5761034a565b8063a0712d6811610159578063a7c6a10011610133578063a7c6a10014610725578063aa6e04341461073a578063aaf166601461075a578063adb4a9ad1461077a5761034a565b8063a0712d68146106d0578063a1e401a9146106f0578063a59d6986146107105761034a565b80639a5ef3691161018a5780639a5ef369146106885780639a9af2211461069b5780639ec5a894146106bb5761034a565b8063792b55b61461063557806399da775b146106555780639a408321146106755761034a565b8063415f12401161027f57806353ffa18b116102285780636a4f4b05116102025780636a4f4b05146105d85780636b9f96ea146105f85780636fd522981461060d5780637239d2b9146106205761034a565b806353ffa18b1461058e5780635641ec03146105ae5780635aa6e675146105c35761034a565b80634aaf7c65116102595780634aaf7c65146105375780634c3a8e0214610559578063538ba4f9146105795761034a565b8063415f1240146104e257806345ee07551461050257806345f867b3146105225761034a565b8063238efcbc116102ec57806338d07436116102c657806338d074361461046a5780633bbd64bc146104985780633fc8cef3146104b8578063411d6fb5146104cd5761034a565b8063238efcbc146104205780632670fdd81461043557806330d4d190146104555761034a565b8063158ef93e1161031d578063158ef93e146103bc5780631718a68f146103de57806322c37b75146104005761034a565b80630510111e1461034f57806309dac0611461037a5780630abb60351461039c5761034a565b3661034a57005b600080fd5b34801561035b57600080fd5b506103646108f8565b6040516103719190615376565b60405180910390f35b34801561038657600080fd5b5061039a6103953660046145fb565b610904565b005b3480156103a857600080fd5b5061039a6103b73660046145fb565b610a26565b3480156103c857600080fd5b506103d1610b34565b60405161037191906148d0565b3480156103ea57600080fd5b506103f3610b3d565b60405161037191906147b2565b34801561040c57600080fd5b5061039a61041b3660046146d4565b610b59565b34801561042c57600080fd5b5061039a610baf565b34801561044157600080fd5b506103f36104503660046146d4565b610c76565b34801561046157600080fd5b50610364610ca2565b34801561047657600080fd5b5061048a610485366004614704565b610cae565b6040516103719291906153a3565b3480156104a457600080fd5b506103d16104b33660046145fb565b610eb3565b3480156104c457600080fd5b506103f3610ec8565b3480156104d957600080fd5b506103d1610ee4565b3480156104ee57600080fd5b5061048a6104fd3660046146d4565b610ef3565b34801561050e57600080fd5b5061039a61051d366004614680565b611099565b34801561052e57600080fd5b5061036461116c565b34801561054357600080fd5b5061054c611172565b604051610371919061536c565b34801561056557600080fd5b5061048a6105743660046146d4565b61118e565b34801561058557600080fd5b506103f361123c565b34801561059a57600080fd5b5061039a6105a93660046146d4565b611241565b3480156105ba57600080fd5b506103d1611356565b3480156105cf57600080fd5b506103f3611364565b3480156105e457600080fd5b5061039a6105f3366004614617565b611380565b34801561060457600080fd5b506103646114c3565b61039a61061b366004614754565b6115e0565b34801561062c57600080fd5b506103f3611997565b34801561064157600080fd5b5061039a6106503660046146d4565b6119b3565b34801561066157600080fd5b5061039a610670366004614680565b611a75565b61039a610683366004614704565b611b49565b61039a610696366004614704565b611e0d565b3480156106a757600080fd5b506103646106b63660046145fb565b612296565b3480156106c757600080fd5b506103f36122c1565b3480156106dc57600080fd5b5061039a6106eb3660046146d4565b6122dd565b3480156106fc57600080fd5b5061036461070b3660046145fb565b612690565b34801561071c57600080fd5b5061039a6126b8565b34801561073157600080fd5b50610364612752565b34801561074657600080fd5b506103646107553660046145fb565b612763565b34801561076657600080fd5b506103646107753660046146d4565b61279a565b34801561078657600080fd5b5061039a6107953660046145fb565b6127b3565b3480156107a657600080fd5b506103646128c1565b3480156107bb57600080fd5b5061039a6107ca3660046145fb565b6128c7565b3480156107db57600080fd5b5061039a6107ea3660046145fb565b612a2a565b3480156107fb57600080fd5b5061048a61080a3660046146d4565b612ac0565b34801561081b57600080fd5b506103d161082a3660046145fb565b612c69565b34801561083b57600080fd5b5061039a61084a3660046145fb565b612c7e565b34801561085b57600080fd5b50610364612d8c565b34801561087057600080fd5b506103f3612d92565b34801561088557600080fd5b506103f3612dae565b34801561089a57600080fd5b506103646108a93660046145fb565b612dca565b3480156108ba57600080fd5b506103f3612dfa565b3480156108cf57600080fd5b5061048a6108de366004614733565b612e16565b3480156108ef57600080fd5b50610364612ea1565b673782dace9d90000081565b60045473ffffffffffffffffffffffffffffffffffffffff16331461095e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166109ab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610955906151e7565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790556040517fdc117600f93282860144d2cd2745f8e2e15c3ca2a32b4290c30f7cd1ae7ffcb990610a1b9083906147b2565b60405180910390a150565b60045473ffffffffffffffffffffffffffffffffffffffff163314610a77576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b73ffffffffffffffffffffffffffffffffffffffff8116610ac4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614989565b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790556040517fc9e2377236eab4280090ce8f2317332649736d92f00dcf20a8dd6684ec5e783990610a1b9083906147b2565b600c5460ff1681565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b60045473ffffffffffffffffffffffffffffffffffffffff163314610baa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b600b55565b60055473ffffffffffffffffffffffffffffffffffffffff163314610c00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614ef2565b600554600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691821790556040517f9d3e522e1e47a2f6009739342b9cc7b252a1888154e843ab55ee1c81745795ab90610a1b9083906147b2565b600080610c84601184612f04565b5473ffffffffffffffffffffffffffffffffffffffff169392505050565b670de0b6b3a764000081565b60008060026000541415610cee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b6002600055610cfc33612f2b565b158015610d0857503332145b610d3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b0e565b600c5460ff16610d7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b336000908152600f6020526040902060038101544311610dc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614fbd565b610dd181600d612f31565b600080610ddf338888612f8d565b60408051808201909152601b81527f4578636565647320776974686472617761626c6520616d6f756e74000000000060208201528554929450909250610e27919083906132b5565b835560408051606081019091526031808252610e5091600d9161542460208301398591906132fb565b3373ffffffffffffffffffffffffffffffffffffffff167fb3ad69dc1d2c6b1f5f5b0927ffd8ee8f1437a156253c8f6dccc75e6f8e4fd38b888484604051610e9a939291906153b1565b60405180910390a2600160005590969095509350505050565b60126020526000908152604090205460ff1681565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b600c5462010000900460ff1681565b60008060026000541415610f33576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b6002600055610f4133612f2b565b158015610f4d57503332145b610f83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b0e565b600c5460ff16610fbf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b336000908152600f60205260409020610fd981600d612f31565b8060010154841115610fed57806001015493505b600080610ffc30876000612f8d565b9150915061100982613344565b60408051602081019091526000815283546110259183906132b5565b835560408051602081019091526000815260018401546110469184906132b5565b600184015560405133907f3ea051727656be6fd11c2260f244f29ff3c70d1fb077bfa73e89d554e9bb95c790611081908990869086906153b1565b60405180910390a26001600055909590945092505050565b60045473ffffffffffffffffffffffffffffffffffffffff163314806110d6575060065473ffffffffffffffffffffffffffffffffffffffff1633145b61110c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614f29565b600c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100831515021790556040517ff0064f2efd0da4bc63eecf2e75590fe8a308eaa526a51c334e50eec09a71104990610a1b9083906148d0565b61271081565b61117a61459b565b506040805160208101909152600d54815290565b600080600260005414156111ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b6002600055600c5460ff1661120f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b600061121c601185612f04565b905061122c848260010154613508565b6001600055909590945092505050565b600081565b60045473ffffffffffffffffffffffffffffffffffffffff163314611292576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b670de0b6b3a76400008110156112d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614c7c565b673782dace9d900000811115611316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614cd9565b60408051602081018252829052600d829055517ff78180bc708b1292177c888900951cd66a39faf48dc7b6d111e93285dbbe55a090610a1b908390615376565b600c54610100900460ff1681565b60045473ffffffffffffffffffffffffffffffffffffffff1681565b60045473ffffffffffffffffffffffffffffffffffffffff1633146113d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b8260005b8181101561147e578383828181106113e957fe5b90506020020160208101906113fe9190614680565b6012600088888581811061140e57fe5b905060200201602081019061142391906145fb565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790556001016113d5565b507fd1721b10ac5fe95d2627d512aa0f92c34ada0347c874adf414cf51af5760ff56858585856040516114b4949392919061482a565b60405180910390a15050505050565b600060026000541415611502576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b6002600055600c5460ff16611543576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b3360009081526012602052604090205460ff1661158c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614ad7565b600c54610100900460ff16156115ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614fce565b6115d66135ed565b9050600160005590565b6002600054141561161d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b600260005561162b33612f2b565b15801561163757503332145b61166d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b0e565b600c5460ff166116a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b8015806116bc57508080156116bc575082155b80156116c757503415155b156116fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d36565b336000908152600f6020526040902061171881600d612f31565b83156118135781156117e55734841461175d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061511c565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b1580156117c757600080fd5b505af11580156117db573d6000803e3d6000fd5b505050505061180a565b60015461180a9073ffffffffffffffffffffffffffffffffffffffff16333087613646565b61181384613344565b821561192c576003546040517f79cc679000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906379cc67909061187190339087906004016147d3565b600060405180830381600087803b15801561188b57600080fd5b505af115801561189f573d6000803e3d6000fd5b50506003546040517f288aafcb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116925063288aafcb91506118f9908690600401615376565b600060405180830381600087803b15801561191357600080fd5b505af1158015611927573d6000803e3d6000fd5b505050505b600061193885856136e9565b600183015490915061194a9082613728565b600183015560405133907fbade234341a40ca3c71df59b3ca02b8bb65b491a098af970953228b4f4a5d38f9061198390889088906153a3565b60405180910390a250506001600055505050565b60075473ffffffffffffffffffffffffffffffffffffffff1681565b60045473ffffffffffffffffffffffffffffffffffffffff163314611a04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b612710811115611a40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614e95565b60098190556040517fc36862a253ff42cc71f4f200d3c62e8e5eaaece01041fc6900aeace64ade72a890610a1b908390615376565b60045473ffffffffffffffffffffffffffffffffffffffff16331480611ab2575060065473ffffffffffffffffffffffffffffffffffffffff1633145b611ae8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614f29565b600c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff1662010000831515021790556040517fca5bdce9cd3e7e41a11035b530ba304b2e5d57e39872a18c079cb3fb7a48b6c290610a1b9083906148d0565b60026000541415611b86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b6002600055611b9433612f2b565b158015611ba057503332145b611bd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b0e565b600c5460ff16611c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b600c54610100900460ff1615611c54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614fce565b336000908152600f60205260409020611c6e81600d612f31565b8115611d3557348314611cad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061503c565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0846040518263ffffffff1660e01b81526004016000604051808303818588803b158015611d1757600080fd5b505af1158015611d2b573d6000803e3d6000fd5b5050505050611d92565b3415611d6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b7a565b600154611d929073ffffffffffffffffffffffffffffffffffffffff16333086613646565b600b548310611da557611da36135ed565b505b600a54611db290846136e9565b600a558054611dc190846136e9565b815543600382015560405133907f59062170a285eb80e8c6b8ced60428442a51910635005233fc4ce084a475845e90611dfb908690615376565b60405180910390a25050600160005550565b60026000541415611e4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b6002600055611e5833612f2b565b158015611e6457503332145b611e9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b0e565b600c5460ff16611ed6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b600c5462010000900460ff1615611f19576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614ddb565b8015611fe057348214611f58576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061503c565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b158015611fc257600080fd5b505af1158015611fd6573d6000803e3d6000fd5b505050505061203d565b3415612018576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b7a565b60015461203d9073ffffffffffffffffffffffffffffffffffffffff16333085613646565b6003546040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906340c10f199061209590339086906004016147d3565b600060405180830381600087803b1580156120af57600080fd5b505af11580156120c3573d6000803e3d6000fd5b505050506120d082613344565b6003546040517f1ac997e000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690631ac997e0906121269030906004016147b2565b60206040518083038186803b15801561213e57600080fd5b505afa158015612152573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217691906146ec565b6003546040517f38e21cce00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906338e21cce906121cc9030906004016147b2565b60206040518083038186803b1580156121e457600080fd5b505afa1580156121f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221c91906146ec565b1115612254576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614f60565b7fda3499e7f2a8b7272740278bd7e34f34f8643fd2dac543aeb2b2df98a2bedb5f33836040516122859291906147d3565b60405180910390a150506001600055565b73ffffffffffffffffffffffffffffffffffffffff166000908152600f602052604090206003015490565b60085473ffffffffffffffffffffffffffffffffffffffff1681565b6002600054141561231a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b600260005561232833612f2b565b15801561233457503332145b61236a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b0e565b600c5460ff166123a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b336000908152600f602052604090206123c081600d612f31565b6002810154828110156124245760006123d98483613728565b60018401549091506123eb90826136e9565b6001840155600060028401556040805160608101909152602780825261241e91600d9161545560208301398591906132fb565b50612434565b61242e8184613728565b60028301555b6003546040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906340c10f199061248c90339087906004016147d3565b600060405180830381600087803b1580156124a657600080fd5b505af11580156124ba573d6000803e3d6000fd5b50506003546040517f1ac997e000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169250631ac997e091506125149030906004016147b2565b60206040518083038186803b15801561252c57600080fd5b505afa158015612540573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256491906146ec565b6003546040517f38e21cce00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116906338e21cce906125ba9030906004016147b2565b60206040518083038186803b1580156125d257600080fd5b505afa1580156125e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061260a91906146ec565b1115612642576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614f60565b60035460405133917f85334969bebc6a94eec30db9687223c52b4a36180ca90c27e42efa05a9202c7491611dfb91879173ffffffffffffffffffffffffffffffffffffffff9091169061537f565b73ffffffffffffffffffffffffffffffffffffffff166000908152600f602052604090205490565b60045473ffffffffffffffffffffffffffffffffffffffff163314612709576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b60045460405173ffffffffffffffffffffffffffffffffffffffff909116904780156108fc02916000818181858888f1935050505015801561274f573d6000803e3d6000fd5b50565b600061275e601161376a565b905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600f6020526040812061279381600d61376e565b9392505050565b6000806127a8601184612f04565b600101549392505050565b60045473ffffffffffffffffffffffffffffffffffffffff163314612804576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b73ffffffffffffffffffffffffffffffffffffffff8116612851576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061492c565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790556040517fe42bb1780117f5788c6e0042e955291223819875891ddf465b8e4fbb85a933e990610a1b9083906147b2565b60095481565b60045473ffffffffffffffffffffffffffffffffffffffff163314612918576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b600c5460ff1615612955576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614b43565b60075473ffffffffffffffffffffffffffffffffffffffff166129a4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610955906149e6565b60085473ffffffffffffffffffffffffffffffffffffffff166129f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614a7a565b6129fc816137ad565b50600c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600c5460ff16612a66576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b60045473ffffffffffffffffffffffffffffffffffffffff163314612ab7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b61274f816137ad565b600c54600090819060ff16612b01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b3360009081526012602052604090205460ff16612b4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614ad7565b6000612b57601185612f04565b9050600080612b6683306139fb565b90925090508115612c25576000612b94612710612b8e60095486612ea790919063ffffffff16565b90613a4e565b90506000612ba28483613728565b9050612bac61459b565b612bc1600a54612bbb84613a9a565b90613adc565b6040805160208101909152600e548152909150612bde9082613b10565b51600e558215612c1257600854600154612c129173ffffffffffffffffffffffffffffffffffffffff918216911685613b40565b8115612c2157612c2182613344565b5050505b7f11d2034f4471d11a13f0f1798ceaf0c9db2812d450a0681958ce7d4f2fb97f098282604051612c569291906153a3565b60405180910390a1909350915050915091565b60106020526000908152604090205460ff1681565b60045473ffffffffffffffffffffffffffffffffffffffff163314612ccf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614d6d565b73ffffffffffffffffffffffffffffffffffffffff8116612d1c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061530f565b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790556040517f05f3326e0527f309d4015dee3bc3f36e650b53fc823bab69c99847814acfafdf90610a1b9083906147b2565b600b5481565b60055473ffffffffffffffffffffffffffffffffffffffff1681565b60065473ffffffffffffffffffffffffffffffffffffffff1681565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600f6020526040812061279381600d613b64565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b60008060026000541415612e56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615244565b6002600055600c5460ff16612e97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615153565b61122c8484613508565b600a5481565b600082612eb657506000612efe565b82820282848281612ec357fe5b0414612efb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614e38565b90505b92915050565b6000826000018281548110612f1557fe5b9060005260206000209060020201905092915050565b3b151590565b6000612f3d8383613bab565b90508260010154811115612f6b576001830180546000909155612f608282613728565b600285015550612f80565b6001830154612f7a9082613728565b60018401555b5060010154600490910155565b6001546040517f70a082310000000000000000000000000000000000000000000000000000000081526000918291829161304391879173ffffffffffffffffffffffffffffffffffffffff16906370a0823190612fee9030906004016147b2565b60206040518083038186803b15801561300657600080fd5b505afa15801561301a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061303e91906146ec565b613c24565b905073ffffffffffffffffffffffffffffffffffffffff8616301461315d578315613139576002546040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d906130be908490600401615376565b600060405180830381600087803b1580156130d857600080fd5b505af11580156130ec573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff8916925083156108fc02915083906000818181858888f19350505050158015613133573d6000803e3d6000fd5b5061315d565b60015461315d9073ffffffffffffffffffffffffffffffffffffffff168783613b40565b8080600061316b8883613728565b9050801561329757600061317f6011613c3a565b9050600080891561326a57613195833086613c65565b6002546040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815292945090925073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d906131ef908590600401615376565b600060405180830381600087803b15801561320957600080fd5b505af115801561321d573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff8f16925084156108fc02915084906000818181858888f19350505050158015613264573d6000803e3d6000fd5b5061327b565b613275838d86613c65565b90925090505b61328586836136e9565b955061329185826136e9565b94505050505b600a546132a49083613728565b600a55509097909650945050505050565b600081848411156132f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095591906148db565b505050900390565b6133058383613c9b565b819061333e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095591906148db565b50505050565b6001546007546040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169263095ea7b3926133a09291169085906004016147d3565b602060405180830381600087803b1580156133ba57600080fd5b505af11580156133ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133f2919061469c565b506007546040517ffb93210800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063fb9321089061344b90309085906004016147d3565b600060405180830381600087803b15801561346557600080fd5b505af1158015613479573d6000803e3d6000fd5b50506003546040517f288aafcb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116925063288aafcb91506134d3908490600401615376565b600060405180830381600087803b1580156134ed57600080fd5b505af1158015613501573d6000803e3d6000fd5b5050505050565b600c546000908190610100900460ff168061353a575060045473ffffffffffffffffffffffffffffffffffffffff1633145b8061354e575061354a6011613cc9565b8414155b613584576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615073565b6000613591601186612f04565b90506000806135a1833088613c65565b91509150867fccbd929f935422b28ee209a0db0556280b0a3d9bc4da58f1d3f0ab4f8a49964783836040516135d79291906153a3565b60405180910390a29093509150505b9250929050565b6000806135fa6011613c3a565b9050600061360782613d22565b90507f860f4701faa0ecdeecd9e9eaae11a8612bbd01c663081f7c0c4e4873df653d69816040516136389190615376565b60405180910390a191505090565b61333e846323b872dd60e01b858585604051602401613667939291906147f9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613dc3565b600082820183811015612efb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614a43565b600082821115613764576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614bb1565b50900390565b5490565b60008061377b8484613bab565b90508061378e5750506001820154612efe565b60018401548082106137a557600092505050612efe565b039392505050565b73ffffffffffffffffffffffffffffffffffffffff81166137fa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610955906152b2565b600154604080517ffc0c546a000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9283169284169163fc0c546a916004808301926020929190829003018186803b15801561386757600080fd5b505afa15801561387b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061389f91906146b8565b73ffffffffffffffffffffffffffffffffffffffff16146138ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061527b565b73ffffffffffffffffffffffffffffffffffffffff811660009081526010602052604090205460ff161561394c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614da4565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260106020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580518082019091529283528201526139b790601190613e79565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f0821015de34e20b0878a40f6f165801417f53b2017016d7321cacee989c8cfa790600090a250565b6000808360010154613a0c85613ee1565b11613a1c575060009050806135e6565b6000613a358560010154613a2f87613ee1565b90613728565b9050613a42858583613f83565b92509250509250929050565b6000808211613a89576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614c45565b818381613a9257fe5b049392505050565b613aa261459b565b6000821580613abf575050670de0b6b3a764000082810290810483145b613ac857600080fd5b604080516020810190915290815292915050565b613ae461459b565b81613aee57600080fd5b604051806020016040528083856000015181613b0657fe5b0490529392505050565b613b1861459b565b82518251810190811015613b2b57600080fd5b60408051602081019091529081529392505050565b613b5f8363a9059cbb60e01b84846040516024016136679291906147d3565b505050565b600080613b718484613bab565b905080613b845750506002820154612efe565b6001840154808211613b9b57600092505050612efe565b6002850154910301905092915050565b6000613bb561459b565b50604080516020810190915260018301548152613bd061459b565b50604080516020810190915260048501548152613bed8282614196565b613bfc57600092505050612efe565b8454613c1b90613c1690613c1085856141e5565b90614200565b61422e565b95945050505050565b6000818310613c335781612efb565b5090919050565b600081613c4681613cc9565b81548110613c5057fe5b90600052602060002090600202019050919050565b6000808080613c75878787613f83565b60018901549193509150613c899082613728565b60018801559092509050935093915050565b600080613cc0613cab858561423d565b60408051602081019091528554815290614196565b13159392505050565b600080613cd58361376a565b905061279360016040518060400160405280601181526020017f5661756c742e4c6973743a20656d707479000000000000000000000000000000815250836132b59092919063ffffffff16565b600080613d2e83614281565b90506127938173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401613d6c91906147b2565b60206040518083038186803b158015613d8457600080fd5b505afa158015613d98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dbc91906146ec565b8490614323565b6060613e25826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166143fd9092919063ffffffff16565b805190915015613b5f5780806020019051810190613e43919061469c565b613b5f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109559061518a565b8154600180820184556000938452602093849020835160029093020180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9093169290921782559190920151910155565b8054604080517fd4c3eea0000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163d4c3eea0916004808301926020929190829003018186803b158015613f4b57600080fd5b505afa158015613f5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612efe91906146ec565b6000806000613f9186614281565b905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231876040518263ffffffff1660e01b8152600401613fce91906147b2565b60206040518083038186803b158015613fe657600080fd5b505afa158015613ffa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061401e91906146ec565b9050600061402b88613ee1565b88546040517ff3fef3a300000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff169063f3fef3a390614083908a908a906004016147d3565b600060405180830381600087803b15801561409d57600080fd5b505af11580156140b1573d6000803e3d6000fd5b50506040517f70a082310000000000000000000000000000000000000000000000000000000081526000925073ffffffffffffffffffffffffffffffffffffffff861691506370a082319061410a908b906004016147b2565b60206040518083038186803b15801561412257600080fd5b505afa158015614136573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061415a91906146ec565b905060006141688285613728565b905060006141758b613ee1565b905060006141838583613728565b929c929b50919950505050505050505050565b8051825160009111156141ca57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612efe565b8151835111156141dc57506001612efe565b50600092915050565b6141ed61459b565b82518251810390811115613b2b57600080fd5b61420861459b565b600082158061422557505082518281029083828161422257fe5b04145b613b2b57600080fd5b51670de0b6b3a7640000900490565b61424561459b565b6000614251848461376e565b9050806142685761426061440c565b915050612efe565b61427981612bbb8660000154613a9a565b949350505050565b8054604080517ffc0c546a000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff169163fc0c546a916004808301926020929190829003018186803b1580156142eb57600080fd5b505afa1580156142ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612efe91906146b8565b60008061432f84614281565b84549091506143589073ffffffffffffffffffffffffffffffffffffffff808416911685613b40565b83546040517fb6b55f2500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063b6b55f25906143ad908690600401615376565b600060405180830381600087803b1580156143c757600080fd5b505af11580156143db573d6000803e3d6000fd5b50505060018501546143ee9150846136e9565b60018501555081905092915050565b60606142798484600085614446565b61441461459b565b5060408051602081019091527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff815290565b606082471015614482576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590614be8565b61448b85612f2b565b6144c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095590615005565b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040516144eb9190614796565b60006040518083038185875af1925050503d8060008114614528576040519150601f19603f3d011682016040523d82523d6000602084013e61452d565b606091505b509150915061453d828286614548565b979650505050505050565b60608315614557575081612793565b8251156145675782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095591906148db565b6040518060200160405280600081525090565b60008083601f8401126145bf578182fd5b50813567ffffffffffffffff8111156145d6578182fd5b60208301915083602080830285010111156135e657600080fd5b8035612efe81615415565b60006020828403121561460c578081fd5b8135612efb816153f3565b6000806000806040858703121561462c578283fd5b843567ffffffffffffffff80821115614643578485fd5b61464f888389016145ae565b90965094506020870135915080821115614667578384fd5b50614674878288016145ae565b95989497509550505050565b600060208284031215614691578081fd5b8135612efb81615415565b6000602082840312156146ad578081fd5b8151612efb81615415565b6000602082840312156146c9578081fd5b8151612efb816153f3565b6000602082840312156146e5578081fd5b5035919050565b6000602082840312156146fd578081fd5b5051919050565b60008060408385031215614716578182fd5b82359150602083013561472881615415565b809150509250929050565b60008060408385031215614745578182fd5b50508035926020909101359150565b600080600060608486031215614768578283fd5b8335925060208401359150604084013561478181615415565b809150509250925092565b1515815260200190565b600082516147a88184602087016153c7565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff9384168152919092166020820152604081019190915260600190565b6040808252810184905260008560608301825b8781101561487a5760208335614852816153f3565b73ffffffffffffffffffffffffffffffffffffffff168352928301929091019060010161483d565b506020915083810382850152806148918683615376565b9050869150835b868110156148c3578383016148b6836148b183876145f0565b61478c565b9093509150600101614898565b5098975050505050505050565b901515815260200190565b60006020825282518060208401526148fa8160408501602087016153c7565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6020808252602c908201527f416c6368656d6973743a207472616e736d75746572206164647265737320636160408201527f6e6e6f74206265203078302e0000000000000000000000000000000000000000606082015260800190565b6020808252602c908201527f416c6368656d6973743a20676f7665726e616e6365206164647265737320636160408201527f6e6e6f74206265203078302e0000000000000000000000000000000000000000606082015260800190565b60208082526036908201527f416c6368656d6973743a2063616e6e6f7420696e697469616c697a652074726160408201527f6e736d75746572206164647265737320746f2030783000000000000000000000606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526033908201527f416c6368656d6973743a2063616e6e6f7420696e697469616c697a652072657760408201527f61726473206164647265737320746f2030783000000000000000000000000000606082015260800190565b60208082526018908201527f416c6368656d6973743a206f6e6c79206b6565706572732e0000000000000000604082015260600190565b6020808252818101527f536f72727920776520646f206e6f742061636365707420636f6e747261637421604082015260600190565b6020808252601e908201527f416c6368656d6973743a20616c726561647920696e697469616c697a65640000604082015260600190565b6020808252600e908201527f6d73672e76616c756520213d2030000000000000000000000000000000000000604082015260600190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60408201527f722063616c6c0000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b60208082526031908201527f416c6368656d6973743a20636f6c6c61746572616c697a6174696f6e206c696d60408201527f69742062656c6f77206d696e696d756d2e000000000000000000000000000000606082015260800190565b60208082526031908201527f416c6368656d6973743a20636f6c6c61746572616c697a6174696f6e206c696d60408201527f69742061626f7665206d6178696d756d2e000000000000000000000000000000606082015260800190565b6020808252600d908201527f626c61636b686f6c652045544800000000000000000000000000000000000000604082015260600190565b6020808252601b908201527f416c6368656d6973743a206f6e6c7920676f7665726e616e63652e0000000000604082015260600190565b60208082526016908201527f4164617074657220616c726561647920696e2075736500000000000000000000604082015260600190565b60208082526022908201527f416c6368656d6973743a20636f6e76657273696f6e732061726520706175736560408201527f642e000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60408201527f7700000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526025908201527f416c6368656d6973743a2068617276657374206665652061626f7665206d617860408201527f696d756d2e000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601f908201527f73656e646572206973206e6f742070656e64696e67476f7665726e616e636500604082015260600190565b60208082526018908201527f21676f7665726e616e6365202626202173656e74696e656c0000000000000000604082015260600190565b60208082526028908201527f416c4554483a20416c6368656d6973742773206365696c696e6720776173206260408201527f726561636865642e000000000000000000000000000000000000000000000000606082015260800190565b602080825260009082015260400190565b60208082526017908201527f656d657267656e637920706175736520656e61626c6564000000000000000000604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b60208082526014908201527f5f616d6f756e7420213d206d73672e76616c7565000000000000000000000000604082015260600190565b60208082526070908201527f416c6368656d6973743a206e6f7420616e20656d657267656e63792c206e6f7460408201527f20676f7665726e616e63652c20616e64207573657220646f6573206e6f74206860608201527f617665207065726d697373696f6e20746f20726563616c6c2066756e6473206660808201527f726f6d20616374697665207661756c740000000000000000000000000000000060a082015260c00190565b6020808252601e908201527f5f636f6c6c61746572616c416d6f756e7420213d206d73672e76616c75650000604082015260600190565b6020808252601b908201527f416c6368656d6973743a206e6f7420696e697469616c697a65642e0000000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60408201527f6f74207375636365656400000000000000000000000000000000000000000000606082015260800190565b6020808252602a908201527f416c6368656d6973743a2073656e74696e656c20616464726573732063616e6e60408201527f6f74206265203078302e00000000000000000000000000000000000000000000606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252601a908201527f416c6368656d6973743a20746f6b656e206d69736d617463682e000000000000604082015260600190565b6020808252602e908201527f416c6368656d6973743a20616374697665207661756c7420616464726573732060408201527f63616e6e6f74206265203078302e000000000000000000000000000000000000606082015260800190565b60208082526029908201527f416c6368656d6973743a207265776172647320616464726573732063616e6e6f60408201527f74206265203078302e0000000000000000000000000000000000000000000000606082015260800190565b9051815260200190565b90815260200190565b91825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b918252602082015260400190565b9283526020830191909152604082015260600190565b60005b838110156153e25781810151838201526020016153ca565b8381111561333e5750506000910152565b73ffffffffffffffffffffffffffffffffffffffff8116811461274f57600080fd5b801515811461274f57600080fdfe416374696f6e20626c6f636b65643a20756e6865616c74687920636f6c6c61746572616c697a6174696f6e20726174696f416c6368656d6973743a204c6f616e2d746f2d76616c756520726174696f206272656163686564a2646970667358221220ac606f4f47d6a62065e11f2374342d0890a2149715b9b0dc8a108852fdc6cb1764736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000100546f2cd4c9d97f798ffc9755e47865ff7ee60000000000000000000000000e78588283aa9ccbec277b40fb8edfa8cc2155a7000000000000000000000000f4b5b84b8f39bc556ed230fa91a0a89bb5e8559b
-----Decoded View---------------
Arg [0] : _token (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [1] : _xtoken (address): 0x0100546F2cD4C9D97f798fFC9755E47865FF7Ee6
Arg [2] : _governance (address): 0x0e78588283aA9CcBeC277b40fB8eDfa8Cc2155a7
Arg [3] : _sentinel (address): 0xf4B5b84b8f39bC556ed230FA91A0A89Bb5E8559b
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [1] : 0000000000000000000000000100546f2cd4c9d97f798ffc9755e47865ff7ee6
Arg [2] : 0000000000000000000000000e78588283aa9ccbec277b40fb8edfa8cc2155a7
Arg [3] : 000000000000000000000000f4b5b84b8f39bc556ed230fa91a0a89bb5e8559b
Loading...
Loading
Loading...
Loading
Net Worth in USD
$5,269.55
Net Worth in ETH
2.666311
Token Allocations
ETH
99.12%
AVAX
0.58%
BNB
0.27%
Others
0.03%
Multichain Portfolio | 34 Chains
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.