Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 747 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Migrate V1Amplif... | 16954504 | 671 days ago | IN | 0 ETH | 0.00046438 | ||||
Renew Amplifier ... | 16811434 | 691 days ago | IN | 0.008 ETH | 0.00095476 | ||||
Create Amplifier... | 16808784 | 692 days ago | IN | 0.016 ETH | 0.00392991 | ||||
Migrate V1Amplif... | 16808651 | 692 days ago | IN | 0 ETH | 0.00670545 | ||||
Migrate V1Amplif... | 16808449 | 692 days ago | IN | 0 ETH | 0.01103267 | ||||
Renew Amplifier | 16808282 | 692 days ago | IN | 0.016 ETH | 0.00146024 | ||||
Claim ETH Batch | 16802056 | 693 days ago | IN | 0 ETH | 0.01793345 | ||||
Renew Amplifier ... | 16802036 | 693 days ago | IN | 0.016 ETH | 0.00389429 | ||||
Renew Amplifier ... | 16800669 | 693 days ago | IN | 0.008 ETH | 0.00186622 | ||||
Claim AMPLIFI | 16800504 | 693 days ago | IN | 0 ETH | 0.01200234 | ||||
Claim AMPLIFI | 16800489 | 693 days ago | IN | 0 ETH | 0.01182048 | ||||
Claim AMPLIFI | 16800487 | 693 days ago | IN | 0 ETH | 0.01218185 | ||||
Renew Amplifier ... | 16797456 | 693 days ago | IN | 0.008 ETH | 0.00142418 | ||||
Renew Amplifier ... | 16797450 | 693 days ago | IN | 0.008 ETH | 0.00152641 | ||||
Renew Amplifier ... | 16796937 | 693 days ago | IN | 0.008 ETH | 0.00097353 | ||||
Renew Amplifier ... | 16796935 | 693 days ago | IN | 0.008 ETH | 0.00099086 | ||||
Claim ETH Batch | 16794594 | 694 days ago | IN | 0 ETH | 0.05011698 | ||||
Claim ETH Batch | 16794592 | 694 days ago | IN | 0 ETH | 0.00110056 | ||||
Claim ETH Batch | 16794587 | 694 days ago | IN | 0 ETH | 0.03050998 | ||||
Renew Amplifier ... | 16794566 | 694 days ago | IN | 0.2 ETH | 0.00805104 | ||||
Renew Amplifier | 16794548 | 694 days ago | IN | 0.008 ETH | 0.00154443 | ||||
Renew Amplifier ... | 16793405 | 694 days ago | IN | 0.04 ETH | 0.00486866 | ||||
Renew Amplifier ... | 16793386 | 694 days ago | IN | 0.04 ETH | 0.00469512 | ||||
Migrate V1Amplif... | 16793384 | 694 days ago | IN | 0 ETH | 0.03972831 | ||||
Renew Amplifier ... | 16791991 | 694 days ago | IN | 0.008 ETH | 0.00166521 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
16811434 | 691 days ago | 0.008 ETH | ||||
16808784 | 692 days ago | 0.016 ETH | ||||
16808282 | 692 days ago | 0.016 ETH | ||||
16802036 | 693 days ago | 0.016 ETH | ||||
16800669 | 693 days ago | 0.008 ETH | ||||
16797456 | 693 days ago | 0.008 ETH | ||||
16797450 | 693 days ago | 0.008 ETH | ||||
16794566 | 694 days ago | 0.2 ETH | ||||
16794548 | 694 days ago | 0.008 ETH | ||||
16793405 | 694 days ago | 0.04 ETH | ||||
16793386 | 694 days ago | 0.04 ETH | ||||
16790936 | 694 days ago | 0.08 ETH | ||||
16790241 | 694 days ago | 0.104 ETH | ||||
16789640 | 694 days ago | 0.008 ETH | ||||
16789635 | 694 days ago | 0.008 ETH | ||||
16785732 | 695 days ago | 0.04 ETH | ||||
16782453 | 695 days ago | 0.04 ETH | ||||
16782449 | 695 days ago | 0.04 ETH | ||||
16782444 | 695 days ago | 0.04 ETH | ||||
16781151 | 695 days ago | 0.088 ETH | ||||
16781104 | 695 days ago | 0.08 ETH | ||||
16781048 | 696 days ago | 0.184 ETH | ||||
16779523 | 696 days ago | 0.008 ETH | ||||
16779519 | 696 days ago | 0.008 ETH | ||||
16779509 | 696 days ago | 0.008 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
AmplifiAmplifierV2
Compiler Version
v0.8.16+commit.07a7930e
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import "openzeppelin-contracts/access/Ownable.sol"; import "openzeppelin-contracts/security/ReentrancyGuard.sol"; import "openzeppelin-contracts/token/ERC20/IERC20.sol"; import "./interfaces/IAmplifi.sol"; import "./interfaces/IAmplifiNode.sol"; import "./interfaces/IUniswap.sol"; import {IAmplifierV2} from "./interfaces/IAmplifierV2.sol"; import "./FusePoolV2.sol"; import "./Types.sol"; import "./Events.sol"; /** * Amplifi * Website: https://perpetualyield.io/ * Telegram: https://t.me/Amplifi_ERC * Twitter: https://twitter.com/amplifidefi */ contract AmplifiAmplifierV2 is Ownable, ReentrancyGuard, IAmplifierV2 { uint16 public maxMonths = 6; uint16 public maxAmplifiersPerMinter = 96; uint256 public gracePeriod = 30 days; uint256 public gammaPeriod = 72 days; uint256 public fuseWaitPeriod = 90 days; uint256 public totalAmplifiers = 0; mapping(uint256 => Types.AmplifierV2) private _amplifiers; mapping(address => uint256) public balanceOf; mapping(address => mapping(uint256 => uint256)) public ownedAmplifiers; mapping(uint256 => uint256) public ownedAmplifiersIndex; mapping(uint256 => bool) public migratedAmplifiers; mapping(Types.FuseProduct => uint256) public fuseLockDurations; mapping(Types.FuseProduct => FusePoolV2) public fusePools; mapping(Types.FuseProduct => uint256) public boosts; uint256 public creationFee = 0.008 ether; uint256 public renewalFee = 0.008 ether; uint256 public fuseFee = 0.008 ether; uint256 public mintPrice = 20e18; uint256[20] public rates = [ 1009000000000, 857650000000, 729002500000, 619652125000, 526704306250, 447698660313, 380543861266, 323462282076, 274942939764, 233701498800, 198646273980, 168849332883, 143521932950, 121993643008, 103694596557, 88140407073, 74919346012, 63681444110, 54129227494, 46009843370 ]; IAmplifi public immutable amplifi; IAmplifiNode public immutable oldAmplifiNode; IUniswapV2Router02 public immutable router; IERC20 public immutable USDC; Types.AmplifierFeeRecipients public feeRecipients; uint16 public claimFee = 750; // Basis for above fee values uint16 public constant bps = 10_000; constructor(IAmplifi _amplifi, IAmplifiNode _oldAmplifiNode, IUniswapV2Router02 _router, IERC20 _usdc) { amplifi = _amplifi; oldAmplifiNode = _oldAmplifiNode; router = _router; USDC = _usdc; feeRecipients = Types.AmplifierFeeRecipients( 0xc766B8c9741BC804FCc378FdE75560229CA3AB1E, 0x58c5a97c717cA3A7969F82D670A9b9FF16545C6F, 0x454cD1e89df17cDB61D868C6D3dBC02bC2c38a17 ); fuseLockDurations[Types.FuseProduct.OneYear] = 365 days; fuseLockDurations[Types.FuseProduct.ThreeYears] = 365 days * 3; fuseLockDurations[Types.FuseProduct.FiveYears] = 365 days * 5; fusePools[Types.FuseProduct.OneYear] = new FusePoolV2(msg.sender, this, 365 days); fusePools[Types.FuseProduct.ThreeYears] = new FusePoolV2(msg.sender, this, 365 days * 3); fusePools[Types.FuseProduct.FiveYears] = new FusePoolV2(msg.sender, this, 365 days * 5); boosts[Types.FuseProduct.OneYear] = 2e18; boosts[Types.FuseProduct.ThreeYears] = 12e18; boosts[Types.FuseProduct.FiveYears] = 36e18; } function createAmplifier(uint256 _months) external payable nonReentrant returns (uint256) { uint256 payment = getRenewalFeeForMonths(_months) + creationFee; require(msg.value == payment, "Invalid Ether value provided"); require(balanceOf[msg.sender] < maxAmplifiersPerMinter, "Too many amplifiers"); require(amplifi.burnForAmplifier(msg.sender, mintPrice), "Not able to burn"); uint256 id = _createAmplifier(_months); (bool success,) = feeRecipients.validatorAcquisition.call{value: payment}(""); require(success, "Could not send ETH"); return id; } function createAmplifierBatch(uint256 _amount, uint256 _months) external payable nonReentrant returns (uint256[] memory ids) { uint256 payment = (getRenewalFeeForMonths(_months) + creationFee) * _amount; require(msg.value == payment, "Invalid Ether value provided"); require(balanceOf[msg.sender] + _amount <= maxAmplifiersPerMinter, "Too many amplifiers"); require(amplifi.burnForAmplifier(msg.sender, mintPrice * _amount), "Not able to burn"); ids = new uint256[](_amount); for (uint256 i = 0; i < _amount;) { ids[i] = _createAmplifier(_months); unchecked { ++i; } } (bool success,) = feeRecipients.validatorAcquisition.call{value: payment}(""); require(success, "Could not send ETH"); return ids; } function _createAmplifier(uint256 _months) internal returns (uint256) { require(_months > 0 && _months <= maxMonths, "Must be 1-6 months"); uint256 id; unchecked { id = totalAmplifiers++; } _amplifiers[id] = Types.AmplifierV2({ fuseProduct: Types.FuseProduct.None, minter: msg.sender, numClaims: 0, created: uint48(block.timestamp), expires: uint48(block.timestamp + 30 days * _months), lastClaimed: 0, fused: 0, unlocks: 0 }); uint256 length; unchecked { length = balanceOf[msg.sender]++; } ownedAmplifiers[msg.sender][length] = id; ownedAmplifiersIndex[id] = length; emit Events.AmplifierCreated(id, msg.sender, _months); return id; } function renewAmplifier(uint256 _id, uint256 _months) external payable nonReentrant { uint256 payment = getRenewalFeeForMonths(_months); require(msg.value == payment, "Invalid Ether value provided"); _renewAmplifier(_id, _months); (bool success,) = feeRecipients.validatorAcquisition.call{value: payment}(""); require(success, "Could not send ETH"); } function renewAmplifierBatch(uint256[] calldata _ids, uint256 _months) external payable nonReentrant { uint256 length = _ids.length; uint256 payment = (getRenewalFeeForMonths(_months)) * length; require(msg.value == payment, "Invalid Ether value provided"); for (uint256 i = 0; i < length;) { _renewAmplifier(_ids[i], _months); unchecked { ++i; } } (bool success,) = feeRecipients.validatorAcquisition.call{value: payment}(""); require(success, "Could not send ETH"); } function _renewAmplifier(uint256 _id, uint256 _months) internal { Types.AmplifierV2 storage amplifier = _amplifiers[_id]; require(amplifier.minter == msg.sender, "Invalid ownership"); require(amplifier.expires + gracePeriod >= block.timestamp, "Grace period expired"); amplifier.expires += uint48(30 days * _months); require(amplifier.expires < block.timestamp + (30 days * maxMonths), "Too many months"); emit Events.AmplifierRenewed(_id, msg.sender, _months); } function fuseAmplifier(uint256 _id, Types.FuseProduct fuseProduct) external payable nonReentrant { Types.AmplifierV2 storage amplifier = _amplifiers[_id]; require(amplifier.minter == msg.sender, "Invalid ownership"); require(amplifier.fuseProduct == Types.FuseProduct.None, "Already fused"); require(amplifier.expires > block.timestamp, "Amplifier expired"); require(msg.value == fuseFee, "Invalid Ether value provided"); uint48 unlocks = fusePools[fuseProduct].enter(_id); amplifier.fuseProduct = fuseProduct; amplifier.fused = uint48(block.timestamp); amplifier.unlocks = unlocks; emit Events.AmplifierFused(_id, msg.sender, fuseProduct); (bool success,) = feeRecipients.validatorAcquisition.call{value: msg.value}(""); require(success, "Could not send ETH"); } function claimAMPLIFI(uint256 _id) external nonReentrant { uint256 amount = _claimAMPLIFI(_id); amount = takeClaimFee(amount); require(amplifi.transfer(msg.sender, amount)); emit Events.AMPLIFIClaimed(msg.sender, amount); } function claimAMPLIFIBatch(uint256[] calldata _ids) external nonReentrant { uint256 amount; uint256 length = _ids.length; for (uint256 i = 0; i < length;) { amount += _claimAMPLIFI(_ids[i]); unchecked { ++i; } } amount = takeClaimFee(amount); require(amplifi.transfer(msg.sender, amount)); emit Events.AMPLIFIClaimed(msg.sender, amount); } function _claimAMPLIFI(uint256 _id) internal returns (uint256 amount) { Types.AmplifierV2 storage amplifier = _amplifiers[_id]; require(amplifier.minter == msg.sender, "Invalid ownership"); require(amplifier.fuseProduct == Types.FuseProduct.None, "Must be unfused"); require(amplifier.expires > block.timestamp, "Amplifier expired"); amount = getPendingAMPLIFI(_id); amplifier.numClaims++; amplifier.lastClaimed = uint48(block.timestamp); } function claimETH(uint256 _id, uint256[] calldata _blockNumbers) external nonReentrant { _claimETH(_id, _blockNumbers); } function claimETHBatch(uint256[] calldata _ids, uint256[] calldata _blockNumbers) external nonReentrant { uint256 length = _ids.length; for (uint256 i = 0; i < length;) { _claimETH(_ids[i], _blockNumbers); unchecked { ++i; } } } function _claimETH(uint256 _id, uint256[] calldata _blockNumbers) internal { Types.AmplifierV2 storage amplifier = _amplifiers[_id]; require(amplifier.fuseProduct != Types.FuseProduct.None, "Must be fused"); require(block.timestamp - amplifier.fused > fuseWaitPeriod, "Cannot claim ETH yet"); if (_blockNumbers.length != 0) { require(amplifier.expires > block.timestamp, "Amplifier expired"); uint256 amount = fusePools[amplifier.fuseProduct].claim(_id, _blockNumbers); emit Events.ETHClaimed(_id, amplifier.minter, msg.sender, amount); } if (amplifier.unlocks <= block.timestamp) { if (amplifier.expires > block.timestamp) { require(amplifi.transfer(amplifier.minter, boosts[amplifier.fuseProduct])); } fusePools[amplifier.fuseProduct].exit(_id); amplifier.fuseProduct = Types.FuseProduct.None; amplifier.fused = 0; amplifier.unlocks = 0; } } function getPendingAMPLIFI(uint256 _id) public view returns (uint256) { Types.AmplifierV2 memory amplifier = _amplifiers[_id]; uint256 rate = amplifier.numClaims >= rates.length ? rates[rates.length - 1] : rates[amplifier.numClaims]; uint256 amount = (block.timestamp - (amplifier.numClaims > 0 ? amplifier.lastClaimed : amplifier.created)) * (rate); if (amplifier.created < block.timestamp + gammaPeriod) { uint256 _seconds = (block.timestamp + gammaPeriod) - amplifier.created; uint256 _percent = 100; if (_seconds >= 4838400) { _percent = 900; } else if (_seconds >= 4233600) { _percent = 800; } else if (_seconds >= 3628800) { _percent = 700; } else if (_seconds >= 3024000) { _percent = 600; } else if (_seconds >= 2419200) { _percent = 500; } else if (_seconds >= 1814400) { _percent = 400; } else if (_seconds >= 1209600) { _percent = 300; } else if (_seconds >= 604800) { _percent = 200; } uint256 _divisor = amount * _percent; (, uint256 result) = tryDiv(_divisor, 10000); amount -= result; } return amount; } function takeClaimFee(uint256 amount) internal returns (uint256) { uint256 fee = (amount * claimFee) / bps; address[] memory path = new address[](2); path[0] = address(amplifi); path[1] = address(USDC); router.swapExactTokensForTokensSupportingFeeOnTransferTokens(fee, 0, path, address(this), block.timestamp); uint256 usdcToSend = USDC.balanceOf(address(this)) / 2; USDC.transfer(feeRecipients.operations, usdcToSend); USDC.transfer(feeRecipients.developers, usdcToSend); return amount - fee; } function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) { return (false, 0); } return (true, a / b); } } function getRenewalFeeForMonths(uint256 _months) public view returns (uint256) { return renewalFee * _months; } function amplifiers(uint256 _id) public view override returns (Types.AmplifierV2 memory) { return _amplifiers[_id]; } function airdropAmplifiers( address[] calldata _users, uint256[] calldata _months, Types.FuseProduct[] calldata _fuseProducts ) external onlyOwner returns (uint256[] memory ids) { require(_users.length == _months.length && _months.length == _fuseProducts.length, "Lengths not aligned"); uint256 length = _users.length; ids = new uint256[](length); for (uint256 i = 0; i < length;) { ids[i] = _airdropAmplifier(_users[i], _months[i], _fuseProducts[i]); unchecked { ++i; } } return ids; } function _airdropAmplifier(address _user, uint256 _months, Types.FuseProduct _fuseProduct) internal returns (uint256) { require(_months <= maxMonths, "Too many months"); uint256 id; uint256 length; unchecked { id = totalAmplifiers++; length = balanceOf[_user]++; } uint48 fused; uint48 unlocks; if (_fuseProduct != Types.FuseProduct.None) { fused = uint48(block.timestamp); unlocks = fusePools[_fuseProduct].enter(id); } _amplifiers[id] = Types.AmplifierV2({ fuseProduct: _fuseProduct, minter: _user, numClaims: 0, created: uint48(block.timestamp), expires: uint48(block.timestamp + 30 days * _months), lastClaimed: 0, fused: fused, unlocks: unlocks }); ownedAmplifiers[_user][length] = id; ownedAmplifiersIndex[id] = length; return id; } function removeAmplifier(uint256 _id) external onlyOwner { uint256 lastAmplifierIndex = balanceOf[_amplifiers[_id].minter]; uint256 amplifierIndex = ownedAmplifiersIndex[_id]; if (amplifierIndex != lastAmplifierIndex) { uint256 lastAmplifierId = ownedAmplifiers[_amplifiers[_id].minter][lastAmplifierIndex]; ownedAmplifiers[_amplifiers[_id].minter][amplifierIndex] = lastAmplifierId; // Move the last amplifier to the slot of the to-delete token ownedAmplifiersIndex[lastAmplifierId] = amplifierIndex; // Update the moved amplifier's index } // This also deletes the contents at the last position of the array delete ownedAmplifiersIndex[_id]; delete ownedAmplifiers[_amplifiers[_id].minter][lastAmplifierIndex]; balanceOf[_amplifiers[_id].minter]--; totalAmplifiers--; delete _amplifiers[_id]; } function setRates(uint256[] calldata _rates) external onlyOwner { require(_rates.length == rates.length, "Invalid length"); uint256 length = _rates.length; for (uint256 i = 0; i < length;) { rates[i] = _rates[i]; unchecked { ++i; } } } function migrateV1Amplifiers(uint256[] calldata _ids) external returns (uint256[] memory) { uint256 length = _ids.length; uint256[] memory migratedIds = new uint256[](length); for (uint256 i = 0; i < length;) { uint256 id = _ids[i]; require(!migratedAmplifiers[id], "Amplifier already migrated"); Types.Amplifier memory v1Amplifier = oldAmplifiNode.amplifiers(id); require(v1Amplifier.created != 0, "Amplifier doesn't exist"); require(v1Amplifier.expires + gracePeriod >= block.timestamp, "Grace period expired"); require(msg.sender == v1Amplifier.minter, "Amplifier can only be migrated by the minter"); migratedAmplifiers[id] = true; migratedIds[i] = _createMigratedAmplifier(v1Amplifier, id); unchecked { ++i; } } return migratedIds; } function _createMigratedAmplifier(Types.Amplifier memory _v1Amplifier, uint256 _v1AmplifierId) internal returns (uint256) { uint256 id; unchecked { id = totalAmplifiers++; } _amplifiers[id] = Types.AmplifierV2({ fuseProduct: _v1Amplifier.fuseProduct, minter: _v1Amplifier.minter, numClaims: uint16(_v1Amplifier.numClaims), created: uint48(_v1Amplifier.created), expires: uint48(_v1Amplifier.expires), lastClaimed: uint48(_v1Amplifier.lastClaimed), fused: uint48(_v1Amplifier.fused), unlocks: uint48(_v1Amplifier.unlocks) }); if (_v1Amplifier.fuseProduct != Types.FuseProduct.None) { fusePools[_v1Amplifier.fuseProduct].migrateShare(id, uint48(_v1Amplifier.unlocks), false); } uint256 length; unchecked { length = balanceOf[_v1Amplifier.minter]++; } ownedAmplifiers[_v1Amplifier.minter][length] = id; ownedAmplifiersIndex[id] = length; emit Events.AmplifierMigrated(_v1AmplifierId, id, _v1Amplifier.minter); return id; } function setMintPrice(uint256 _mintPrice) external onlyOwner { mintPrice = _mintPrice; } function setMaxMonths(uint16 _maxMonths) external onlyOwner { maxMonths = _maxMonths; } function setFees(uint256 _creationFee, uint256 _renewalFee, uint256 _fuseFee, uint16 _claimFee) external onlyOwner { creationFee = _creationFee; renewalFee = _renewalFee; fuseFee = _fuseFee; claimFee = _claimFee; } function setFuseLockDurations(Types.FuseProduct _fuseProduct, uint256 _duration) external onlyOwner { fuseLockDurations[_fuseProduct] = _duration; } function setFusePool(Types.FuseProduct _fuseProduct, FusePoolV2 _fusePool) external onlyOwner { fusePools[_fuseProduct] = _fusePool; } function setBoosts(Types.FuseProduct _fuseProduct, uint256 _boost) external onlyOwner { boosts[_fuseProduct] = _boost; } function setFeeRecipients(Types.AmplifierFeeRecipients calldata _feeRecipients) external onlyOwner { feeRecipients = _feeRecipients; } function setPeriods(uint256 _gracePeriod, uint256 _gammaPeriod, uint256 _fuseWaitPeriod) external onlyOwner { gracePeriod = _gracePeriod; gammaPeriod = _gammaPeriod; fuseWaitPeriod = _fuseWaitPeriod; } function approveRouter() external onlyOwner { amplifi.approve(address(router), type(uint256).max); } function withdrawETH(address _recipient) external onlyOwner { (bool success,) = _recipient.call{value: address(this).balance}(""); require(success, "Could not send ETH"); } function withdrawToken(IERC20 _token, address _recipient) external onlyOwner { _token.transfer(_recipient, _token.balanceOf(address(this))); } receive() external payable {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions 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 { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^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() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // 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 // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`. // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`. // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a // good first aproximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1; uint256 x = a; if (x >> 128 > 0) { x >>= 128; result <<= 64; } if (x >> 64 > 0) { x >>= 64; result <<= 32; } if (x >> 32 > 0) { x >>= 32; result <<= 16; } if (x >> 16 > 0) { x >>= 16; result <<= 8; } if (x >> 8 > 0) { x >>= 8; result <<= 4; } if (x >> 4 > 0) { x >>= 4; result <<= 2; } if (x >> 2 > 0) { result <<= 1; } // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { uint256 result = sqrt(a); if (rounding == Rounding.Up && result * result < a) { result += 1; } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol) pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toUint248(uint256 value) internal pure returns (uint248) { require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toUint240(uint256 value) internal pure returns (uint240) { require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toUint232(uint256 value) internal pure returns (uint232) { require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.2._ */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toUint216(uint256 value) internal pure returns (uint216) { require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toUint208(uint256 value) internal pure returns (uint208) { require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toUint200(uint256 value) internal pure returns (uint200) { require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toUint192(uint256 value) internal pure returns (uint192) { require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toUint184(uint256 value) internal pure returns (uint184) { require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toUint176(uint256 value) internal pure returns (uint176) { require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toUint168(uint256 value) internal pure returns (uint168) { require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toUint160(uint256 value) internal pure returns (uint160) { require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toUint152(uint256 value) internal pure returns (uint152) { require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toUint144(uint256 value) internal pure returns (uint144) { require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toUint136(uint256 value) internal pure returns (uint136) { require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v2.5._ */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toUint120(uint256 value) internal pure returns (uint120) { require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toUint112(uint256 value) internal pure returns (uint112) { require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toUint104(uint256 value) internal pure returns (uint104) { require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.2._ */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toUint80(uint256 value) internal pure returns (uint80) { require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toUint72(uint256 value) internal pure returns (uint72) { require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v2.5._ */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toUint56(uint256 value) internal pure returns (uint56) { require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toUint48(uint256 value) internal pure returns (uint48) { require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toUint40(uint256 value) internal pure returns (uint40) { require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v2.5._ */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toUint24(uint256 value) internal pure returns (uint24) { require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v2.5._ */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v2.5._ */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. * * _Available since v3.0._ */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toInt248(int256 value) internal pure returns (int248) { require(value >= type(int248).min && value <= type(int248).max, "SafeCast: value doesn't fit in 248 bits"); return int248(value); } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toInt240(int256 value) internal pure returns (int240) { require(value >= type(int240).min && value <= type(int240).max, "SafeCast: value doesn't fit in 240 bits"); return int240(value); } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toInt232(int256 value) internal pure returns (int232) { require(value >= type(int232).min && value <= type(int232).max, "SafeCast: value doesn't fit in 232 bits"); return int232(value); } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.7._ */ function toInt224(int256 value) internal pure returns (int224) { require(value >= type(int224).min && value <= type(int224).max, "SafeCast: value doesn't fit in 224 bits"); return int224(value); } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toInt216(int256 value) internal pure returns (int216) { require(value >= type(int216).min && value <= type(int216).max, "SafeCast: value doesn't fit in 216 bits"); return int216(value); } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toInt208(int256 value) internal pure returns (int208) { require(value >= type(int208).min && value <= type(int208).max, "SafeCast: value doesn't fit in 208 bits"); return int208(value); } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toInt200(int256 value) internal pure returns (int200) { require(value >= type(int200).min && value <= type(int200).max, "SafeCast: value doesn't fit in 200 bits"); return int200(value); } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toInt192(int256 value) internal pure returns (int192) { require(value >= type(int192).min && value <= type(int192).max, "SafeCast: value doesn't fit in 192 bits"); return int192(value); } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toInt184(int256 value) internal pure returns (int184) { require(value >= type(int184).min && value <= type(int184).max, "SafeCast: value doesn't fit in 184 bits"); return int184(value); } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toInt176(int256 value) internal pure returns (int176) { require(value >= type(int176).min && value <= type(int176).max, "SafeCast: value doesn't fit in 176 bits"); return int176(value); } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toInt168(int256 value) internal pure returns (int168) { require(value >= type(int168).min && value <= type(int168).max, "SafeCast: value doesn't fit in 168 bits"); return int168(value); } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toInt160(int256 value) internal pure returns (int160) { require(value >= type(int160).min && value <= type(int160).max, "SafeCast: value doesn't fit in 160 bits"); return int160(value); } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toInt152(int256 value) internal pure returns (int152) { require(value >= type(int152).min && value <= type(int152).max, "SafeCast: value doesn't fit in 152 bits"); return int152(value); } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toInt144(int256 value) internal pure returns (int144) { require(value >= type(int144).min && value <= type(int144).max, "SafeCast: value doesn't fit in 144 bits"); return int144(value); } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toInt136(int256 value) internal pure returns (int136) { require(value >= type(int136).min && value <= type(int136).max, "SafeCast: value doesn't fit in 136 bits"); return int136(value); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128) { require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits"); return int128(value); } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toInt120(int256 value) internal pure returns (int120) { require(value >= type(int120).min && value <= type(int120).max, "SafeCast: value doesn't fit in 120 bits"); return int120(value); } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toInt112(int256 value) internal pure returns (int112) { require(value >= type(int112).min && value <= type(int112).max, "SafeCast: value doesn't fit in 112 bits"); return int112(value); } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toInt104(int256 value) internal pure returns (int104) { require(value >= type(int104).min && value <= type(int104).max, "SafeCast: value doesn't fit in 104 bits"); return int104(value); } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.7._ */ function toInt96(int256 value) internal pure returns (int96) { require(value >= type(int96).min && value <= type(int96).max, "SafeCast: value doesn't fit in 96 bits"); return int96(value); } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toInt88(int256 value) internal pure returns (int88) { require(value >= type(int88).min && value <= type(int88).max, "SafeCast: value doesn't fit in 88 bits"); return int88(value); } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toInt80(int256 value) internal pure returns (int80) { require(value >= type(int80).min && value <= type(int80).max, "SafeCast: value doesn't fit in 80 bits"); return int80(value); } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toInt72(int256 value) internal pure returns (int72) { require(value >= type(int72).min && value <= type(int72).max, "SafeCast: value doesn't fit in 72 bits"); return int72(value); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64) { require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits"); return int64(value); } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toInt56(int256 value) internal pure returns (int56) { require(value >= type(int56).min && value <= type(int56).max, "SafeCast: value doesn't fit in 56 bits"); return int56(value); } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toInt48(int256 value) internal pure returns (int48) { require(value >= type(int48).min && value <= type(int48).max, "SafeCast: value doesn't fit in 48 bits"); return int48(value); } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toInt40(int256 value) internal pure returns (int40) { require(value >= type(int40).min && value <= type(int40).max, "SafeCast: value doesn't fit in 40 bits"); return int40(value); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32) { require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits"); return int32(value); } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toInt24(int256 value) internal pure returns (int24) { require(value >= type(int24).min && value <= type(int24).max, "SafeCast: value doesn't fit in 24 bits"); return int24(value); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16) { require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits"); return int16(value); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8) { require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits"); return int8(value); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. * * _Available since v3.0._ */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; import "./Types.sol"; library Events { event AmplifierCreated(uint256 indexed id, address indexed owner, uint256 months); event AmplifierRenewed(uint256 indexed id, address indexed owner, uint256 months); event AmplifierFused(uint256 indexed id, address indexed owner, Types.FuseProduct indexed fuseProduct); event AmplifierMigrated(uint256 indexed v1AmplifierId, uint256 indexed v2AmplifierId, address indexed owner); event AMPLIFIClaimed(address indexed owner, uint256 amount); event ETHClaimed(uint256 indexed id, address indexed owner, address indexed claimer, uint256 amount); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import "openzeppelin-contracts/access/Ownable.sol"; import "openzeppelin-contracts/token/ERC20/IERC20.sol"; import "openzeppelin-contracts/utils/math/Math.sol"; import "openzeppelin-contracts/utils/math/SafeCast.sol"; import "./interfaces/IUniswap.sol"; import "./interfaces/INetworkV2.sol"; import {IAmplifierV2} from "./interfaces/IAmplifierV2.sol"; import "./Types.sol"; /** * Amplifi * Website: https://perpetualyield.io/ * Telegram: https://t.me/Amplifi_ERC * Twitter: https://twitter.com/amplifidefi */ contract FusePoolV2 is INetworkV2, Ownable { uint256 immutable duration; IAmplifierV2 public amplifierContract; mapping(uint256 => mapping(uint256 => bool)) public hasClaimedPeriod; mapping(uint256 => Types.Pot) public potPerPeriod; mapping(uint256 => uint256) public fuseUnlocks; uint256 public totalSupply; mapping(uint256 => Types.Checkpoint[]) private _checkpoints; Types.Checkpoint[] private _totalSupplyCheckpoints; event PotAccrued(uint256 potAmount); event Claimed(uint256 indexed id, uint256 indexed potBlock, uint256 amount); modifier onlyAmplifier() { require(msg.sender == address(amplifierContract), "Only Amplifier"); _; } constructor(address _owner, IAmplifierV2 _amplifierContract, uint256 _duration) { _transferOwnership(_owner); amplifierContract = _amplifierContract; duration = _duration; } function enter(uint256 _id) external onlyAmplifier returns (uint48) { require(fuseUnlocks[_id] == 0, "Share already exists"); _checkpoints[_id].push(Types.Checkpoint({fromBlock: uint32(block.number), shares: 1})); _writeCheckpoint(_totalSupplyCheckpoints, _add, 1); totalSupply++; uint256 unlocks = duration + block.timestamp; fuseUnlocks[_id] = unlocks; return uint48(unlocks); } function exit(uint256 _id) external onlyAmplifier { require(fuseUnlocks[_id] <= block.timestamp, "Cannot exit yet"); _checkpoints[_id].push(Types.Checkpoint({fromBlock: uint32(block.number), shares: 0})); _writeCheckpoint(_totalSupplyCheckpoints, _subtract, 1); totalSupply--; fuseUnlocks[_id] = 0; } function migrateShare(uint256 _id, uint48 _unlocks, bool _allowOverwrite) external override onlyAmplifier { require(fuseUnlocks[_id] == 0 || _allowOverwrite, "Share already exists"); _checkpoints[_id].push(Types.Checkpoint({fromBlock: uint32(block.number), shares: 1})); fuseUnlocks[_id] = _unlocks; unchecked { totalSupply++; } _writeCheckpoint(_totalSupplyCheckpoints, _add, 1); } function pot() external payable onlyOwner { potPerPeriod[block.number] = Types.Pot({timestamp: uint48(block.timestamp), value: SafeCast.toUint208(msg.value)}); emit PotAccrued(msg.value); } function claim(uint256 _id, uint256[] calldata _blockNumbers) external onlyAmplifier returns (uint256) { uint256 owed; uint256 length = _blockNumbers.length; for (uint256 i = 0; i < length;) { uint256 claimAmount = _claim(_blockNumbers[i], _id); emit Claimed(_id, _blockNumbers[i], claimAmount); owed += claimAmount; unchecked { ++i; } } _claimPayments(owed, _id); return owed; } function _claim(uint256 _blockNumber, uint256 _id) internal returns (uint256) { require(!hasClaimedPeriod[_id][_blockNumber], "Already claimied this period"); require(fuseUnlocks[_id] > potPerPeriod[_blockNumber].timestamp, "Period after unlock time"); hasClaimedPeriod[_id][_blockNumber] = true; return getClaimAmount(_blockNumber, _id); } function _claimPayments(uint256 owed, uint256 _id) internal { require(owed > 0, "No ETH claimable"); Types.AmplifierV2 memory amplifier = amplifierContract.amplifiers(_id); (bool success,) = amplifier.minter.call{value: owed}(""); require(success, "Could not send ETH"); } function _writeCheckpoint( Types.Checkpoint[] storage ckpts, function(uint256, uint256) view returns (uint256) op, uint256 delta ) internal returns (uint256 oldWeight, uint256 newWeight) { uint256 pos = ckpts.length; oldWeight = pos == 0 ? 0 : ckpts[pos - 1].shares; newWeight = op(oldWeight, delta); if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) { ckpts[pos - 1].shares = SafeCast.toUint224(newWeight); } else { ckpts.push( Types.Checkpoint({fromBlock: uint32(block.number), shares: SafeCast.toUint224(newWeight)}) ); } } function _add(uint256 a, uint256 b) private pure returns (uint256) { return a + b; } function _subtract(uint256 a, uint256 b) private pure returns (uint256) { return a - b; } function getClaimAmount(uint256 _blockNumber, uint256 _id) public view returns (uint256) { return (getPastShares(_id, _blockNumber) * potPerPeriod[_blockNumber].value) / (getPastTotalSupply(_blockNumber)); } function ETHOwed(uint256[] memory _blockNumbers, uint256 _id) public view returns (uint256) { uint256 owed = 0; for (uint256 i = 0; i < _blockNumbers.length;) { uint256 blockNumber = _blockNumbers[i]; if (!hasClaimedPeriod[_id][blockNumber]) { owed += (getPastShares(_id, blockNumber) * potPerPeriod[blockNumber].value) / (getPastTotalSupply(blockNumber)); } unchecked { ++i; } } return owed; } function getPastShares(uint256 id, uint256 blockNumber) public view returns (uint256) { require(blockNumber < block.number, "block not yet mined"); return _checkpointsLookup(_checkpoints[id], blockNumber); } function getPastTotalSupply(uint256 blockNumber) public view returns (uint256) { require(blockNumber < block.number, "block not yet mined"); return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber); } function _checkpointsLookup(Types.Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) { // We run a binary search to look for the earliest checkpoint taken after `blockNumber`. // // During the loop, the index of the wanted checkpoint remains in the range [low-1, high). // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant. // - If the middle checkpoint is after `blockNumber`, we look in [low, mid) // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high) // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not // out of bounds (in which case we're looking too far in the past and the result is 0). // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out // the same. uint256 high = ckpts.length; uint256 low = 0; while (low < high) { uint256 mid = Math.average(low, high); if (ckpts[mid].fromBlock > blockNumber) { high = mid; } else { low = mid + 1; } } return high == 0 ? 0 : ckpts[high - 1].shares; } function withdrawETH(address _recipient) external onlyOwner { (bool success,) = _recipient.call{value: address(this).balance}(""); require(success, "Could not send ETH"); } function withdrawToken(IERC20 _token, address _recipient) external onlyOwner { _token.transfer(_recipient, _token.balanceOf(address(this))); } function emergencyDeposit() external payable onlyOwner {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; library Types { struct FeeRecipients { address operations; address validatorAcquisition; address PCR; address yield; address xChainValidatorAcquisition; address indexFundPools; address gAMPRewardsPool; address OTCSwap; address rescueFund; address protocolImprovement; address developers; } struct Fees { uint16 operations; uint16 validatorAcquisition; uint16 PCR; uint16 yield; uint16 xChainValidatorAcquisition; uint16 indexFundPools; uint16 gAMPRewardsPool; uint16 OTCSwap; uint16 rescueFund; uint16 protocolImprovement; uint16 developers; } struct Share { uint256 amount; uint256 totalExcluded; uint256 totalRealised; uint256 started; uint256 unlocks; } enum FuseProduct { None, OneYear, ThreeYears, FiveYears } struct Amplifier { FuseProduct fuseProduct; address minter; uint256 created; uint256 expires; uint256 numClaims; uint256 lastClaimed; uint256 fused; uint256 unlocks; uint256 lastFuseClaimed; } struct AmplifierV2 { FuseProduct fuseProduct; address minter; uint16 numClaims; uint48 lastClaimed; uint48 created; uint48 expires; uint48 fused; uint48 unlocks; } struct AmplifierFeeRecipients { address operations; address validatorAcquisition; address developers; } struct Transistor { address minter; uint256 created; uint256 expires; uint256 numClaims; uint256 lastClaimed; } struct TransistorFeeRecipients { address creationFee; address creationTax; address renewalFee; address reverseFee; address claimFeeOperations; address claimFeeDevelopers; } struct Checkpoint { uint32 fromBlock; uint224 shares; } struct Pot { uint48 timestamp; uint208 value; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import "openzeppelin-contracts/token/ERC20/IERC20.sol"; interface IAmplifi is IERC20 { function burnForAmplifier(address _burnee, uint256 _amount) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {Types} from "../Types.sol"; interface IAmplifiNode { function amplifiers(uint256) external view returns (Types.Amplifier memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {Types} from "../Types.sol"; interface IAmplifierV2 { function amplifiers(uint256) external view returns (Types.AmplifierV2 memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.16; interface INetworkV2 { function enter(uint256 _id) external returns (uint48); function exit(uint256 _id) external; function migrateShare(uint256 _id, uint48 _unlocks, bool _allowOverwrite) external; function pot() external payable; function claim(uint256 _id, uint256[] calldata _blockNumbers) external returns (uint256); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.13; interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint256 value); event Transfer(address indexed from, address indexed to, uint256 value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool); function transfer(address to, uint256 value) external returns (bool); function transferFrom( address from, address to, uint256 value ) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint256); function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; event Mint(address indexed sender, uint256 amount0, uint256 amount1); event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to); event Swap( address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint256); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns ( uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast ); function price0CumulativeLast() external view returns (uint256); function price1CumulativeLast() external view returns (uint256); function kLast() external view returns (uint256); function mint(address to) external returns (uint256 liquidity); function burn(address to) external returns (uint256 amount0, uint256 amount1); function swap( uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data ) external; function skim(address to) external; function sync() external; function initialize(address, address) external; } interface IUniswapV2Factory { event PairCreated(address indexed token0, address indexed token1, address pair, uint256); function feeTo() external view returns (address); function feeToSetter() external view returns (address); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint256) external view returns (address pair); function allPairsLength() external view returns (uint256); function createPair(address tokenA, address tokenB) external returns (address pair); function setFeeTo(address) external; function setFeeToSetter(address) external; } interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns ( uint256 amountA, uint256 amountB, uint256 liquidity ); function addLiquidityETH( address token, uint256 amountTokenDesired, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external payable returns ( uint256 amountToken, uint256 amountETH, uint256 liquidity ); function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts); } interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external returns (uint256 amountETH); function swapExactTokensForETHSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable; }
{ "remappings": [ "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/", "solmate/=lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IAmplifi","name":"_amplifi","type":"address"},{"internalType":"contract IAmplifiNode","name":"_oldAmplifiNode","type":"address"},{"internalType":"contract IUniswapV2Router02","name":"_router","type":"address"},{"internalType":"contract IERC20","name":"_usdc","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"USDC","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"},{"internalType":"uint256[]","name":"_months","type":"uint256[]"},{"internalType":"enum Types.FuseProduct[]","name":"_fuseProducts","type":"uint8[]"}],"name":"airdropAmplifiers","outputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"amplifi","outputs":[{"internalType":"contract IAmplifi","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"amplifiers","outputs":[{"components":[{"internalType":"enum Types.FuseProduct","name":"fuseProduct","type":"uint8"},{"internalType":"address","name":"minter","type":"address"},{"internalType":"uint16","name":"numClaims","type":"uint16"},{"internalType":"uint48","name":"lastClaimed","type":"uint48"},{"internalType":"uint48","name":"created","type":"uint48"},{"internalType":"uint48","name":"expires","type":"uint48"},{"internalType":"uint48","name":"fused","type":"uint48"},{"internalType":"uint48","name":"unlocks","type":"uint48"}],"internalType":"struct Types.AmplifierV2","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"approveRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Types.FuseProduct","name":"","type":"uint8"}],"name":"boosts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bps","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"claimAMPLIFI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"claimAMPLIFIBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256[]","name":"_blockNumbers","type":"uint256[]"}],"name":"claimETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_blockNumbers","type":"uint256[]"}],"name":"claimETHBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimFee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_months","type":"uint256"}],"name":"createAmplifier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_months","type":"uint256"}],"name":"createAmplifierBatch","outputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"creationFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeRecipients","outputs":[{"internalType":"address","name":"operations","type":"address"},{"internalType":"address","name":"validatorAcquisition","type":"address"},{"internalType":"address","name":"developers","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"enum Types.FuseProduct","name":"fuseProduct","type":"uint8"}],"name":"fuseAmplifier","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"fuseFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Types.FuseProduct","name":"","type":"uint8"}],"name":"fuseLockDurations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Types.FuseProduct","name":"","type":"uint8"}],"name":"fusePools","outputs":[{"internalType":"contract FusePoolV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fuseWaitPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gammaPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getPendingAMPLIFI","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_months","type":"uint256"}],"name":"getRenewalFeeForMonths","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gracePeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAmplifiersPerMinter","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMonths","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"migrateV1Amplifiers","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"migratedAmplifiers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oldAmplifiNode","outputs":[{"internalType":"contract IAmplifiNode","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"ownedAmplifiers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ownedAmplifiersIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rates","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"removeAmplifier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_months","type":"uint256"}],"name":"renewAmplifier","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256","name":"_months","type":"uint256"}],"name":"renewAmplifierBatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renewalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Types.FuseProduct","name":"_fuseProduct","type":"uint8"},{"internalType":"uint256","name":"_boost","type":"uint256"}],"name":"setBoosts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"operations","type":"address"},{"internalType":"address","name":"validatorAcquisition","type":"address"},{"internalType":"address","name":"developers","type":"address"}],"internalType":"struct Types.AmplifierFeeRecipients","name":"_feeRecipients","type":"tuple"}],"name":"setFeeRecipients","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_creationFee","type":"uint256"},{"internalType":"uint256","name":"_renewalFee","type":"uint256"},{"internalType":"uint256","name":"_fuseFee","type":"uint256"},{"internalType":"uint16","name":"_claimFee","type":"uint16"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum Types.FuseProduct","name":"_fuseProduct","type":"uint8"},{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"setFuseLockDurations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum Types.FuseProduct","name":"_fuseProduct","type":"uint8"},{"internalType":"contract FusePoolV2","name":"_fusePool","type":"address"}],"name":"setFusePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_maxMonths","type":"uint16"}],"name":"setMaxMonths","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintPrice","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gracePeriod","type":"uint256"},{"internalType":"uint256","name":"_gammaPeriod","type":"uint256"},{"internalType":"uint256","name":"_fuseWaitPeriod","type":"uint256"}],"name":"setPeriods","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_rates","type":"uint256[]"}],"name":"setRates","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalAmplifiers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"}],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6002805463ffffffff19166260000617905562278d00600355625eec006004556276a7006005556000600655661c6bf526340000600f81905560108190556011556801158e460913d0000060125561038060405264eaed162a0061010090815264c7afec70806101205264a9bbef5fa06101405264904625114861016052647aa205e84a6101805264683ceb6bd96101a05264589a2e82126101c052644b4fdabb5c6101e052644003e0527461020052643669b1dfb061022052642e403d97bc61024052642750345a936102605264216a92e69661028052641c676344006102a052641824adf9cd6102c05264148593e1216102e0526411718a7f5c61030052640ed3b5b90e61032052640c9a5a76e661034052640ab6667eaa610360526200012d9060139060146200054e565b50602a805461ffff19166102ee1790553480156200014a57600080fd5b50604051620062e1380380620062e18339810160408190526200016d91620005d8565b6200017833620004fe565b600180556001600160a01b0384811660805283811660a05282811660c052811660e0526040805160608101825273c766b8c9741bc804fcc378fde75560229ca3ab1e8082527358c5a97c717ca3a7969f82d670a9b9ff16545c6f602080840182905273454cd1e89df17cdb61d868c6d3dbc02bc2c38a17938501849052602780546001600160a01b03199081169094179055602880548416909217909155602980549092169092179055600c90526301e133807fd421a5181c571bba3f01190c922c3b2a896fc1d84e86c9f17ac10e67ebef8b5c8190556305a39a807f5d6016397a73f5e079297ac5a36fef17b4d9c3831618e63ab105738020ddd72055600360005263096601807fc0da782485e77ae272268ae0a3ff44c1552ecb60b3743924de17a815e0a3cfd755905133913091620002b3906200059a565b6001600160a01b0393841681529290911660208301526040820152606001604051809103906000f080158015620002ee573d6000803e3d6000fd5b506001600052600d6020527ffd54ff1ed53f34a900b24c5ba64f85761163b5d82d98a47b9bd80e45466993c580546001600160a01b0319166001600160a01b0392909216919091179055604051339030906305a39a809062000350906200059a565b6001600160a01b0393841681529290911660208301526040820152606001604051809103906000f0801580156200038b573d6000803e3d6000fd5b506002600052600d6020527f10a81eed9d63d16face5e76357905348e6253d3394086026bb2bf2145d7cc24980546001600160a01b0319166001600160a01b039290921691909117905560405133903090630966018090620003ed906200059a565b6001600160a01b0393841681529290911660208301526040820152606001604051809103906000f08015801562000428573d6000803e3d6000fd5b507f26b4a10d0f0b04925c23bd4480ee147c916e5e87a7d68206a533dad160ac81e280546001600160a01b0319166001600160a01b03929092169190911790555050600e6020525050671bc16d674ec800007fa7c5ba7114a813b50159add3a36832908dc83db71d0b9a24c2ad0f83be9582075567a688906bd8b000007f9adb202b1492743bc00c81d33cdc6423fa8c79109027eb6a845391e8fc1f04815560036000526801f399b1438a1000007fe0283e559c29e31ee7f56467acc9dd307779c843a883aeeb3bf5c6128c9081445562000640565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b826014810192821562000588579160200282015b8281111562000588578251829064ffffffffff1690559160200191906001019062000562565b5062000596929150620005a8565b5090565b61193780620049aa83390190565b5b80821115620005965760008155600101620005a9565b6001600160a01b0381168114620005d557600080fd5b50565b60008060008060808587031215620005ef57600080fd5b8451620005fc81620005bf565b60208601519094506200060f81620005bf565b60408601519093506200062281620005bf565b60608601519092506200063581620005bf565b939692955090935050565b60805160a05160c05160e0516142ce620006dc600039600081816107ed01528181612e7901528181612f6501528181613006015261309d015260008181610a3501528181611b6b0152612ed00152600081816104540152610c5701526000818161095f01528181610f2a015281816113fe015281816118e501528181611b9b0152818161227e01528181612e25015261336d01526142ce6000f3fe6080604052600436106103545760003560e01c80636991b45c116101c6578063bbb7a429116100f7578063f2fde38b11610095578063f98d4a881161006f578063f98d4a8814610a57578063f9b1be7814610a6d578063fa8711aa14610a9a578063fe0e6ee914610aba57600080fd5b8063f2fde38b146109e3578063f4a0a52814610a03578063f887ea4014610a2357600080fd5b8063dce0b4e4116100d1578063dce0b4e414610981578063dd418ae214610997578063de1f0713146109b7578063ed8c5e83146109cd57600080fd5b8063bbb7a4291461090c578063c71fcd271461092d578063d904ecd91461094d57600080fd5b806399d32fc411610164578063ab98f4ae1161013e578063ab98f4ae1461087e578063ac597cb21461089e578063b6ed9d6f146108b1578063b72fc876146108cc57600080fd5b806399d32fc41461082d578063a06db7dc14610848578063a3a742d51461085e57600080fd5b806378fdb555116101a057806378fdb555146107a85780637eed4a39146107c857806389a30271146107db5780638da5cb5b1461080f57600080fd5b80636991b45c1461075157806370a0823114610766578063715018a61461079357600080fd5b80633aeac4e1116102a05780634c20f90a1161023e578063601ea33111610218578063601ea331146106df5780636817c76c146106f25780636823732914610708578063690d83201461073157600080fd5b80634c20f90a146106725780635bf3df4e146106925780635f8ee864146106bf57600080fd5b80633f0609b41161027a5780633f0609b4146105f2578063417314591461061257806343840c52146106325780634b9497b21461065257600080fd5b80633aeac4e1146105925780633b973802146105b25780633db59093146105d257600080fd5b80631267a00a1161030d57806325627b54116102e757806325627b54146104fb5780632f346b691461050e57806332d4268a14610546578063388fdd0c1461055c57600080fd5b80631267a00a1461048e57806317b2e40a146104bb578063208e831a146104e857600080fd5b8063080b301e146103605780630adfdcb9146103895780630cf4680e146103e05780630d06279e146104025780630f3ac4a31461042257806310909c7d1461044257600080fd5b3661035b57005b600080fd5b34801561036c57600080fd5b5061037660105481565b6040519081526020015b60405180910390f35b34801561039557600080fd5b506027546028546029546103b6926001600160a01b03908116928116911683565b604080516001600160a01b0394851681529284166020840152921691810191909152606001610380565b3480156103ec57600080fd5b506104006103fb3660046138aa565b610ae7565b005b34801561040e57600080fd5b5061040061041d3660046138d9565b610b07565b34801561042e57600080fd5b5061037661043d366004613905565b610b4c565b34801561044e57600080fd5b506104767f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610380565b34801561049a57600080fd5b506104ae6104a9366004613963565b610b62565b60405161038091906139a5565b3480156104c757600080fd5b506103766104d63660046139e9565b600e6020526000908152604090205481565b6103766104f6366004613905565b610e46565b610400610509366004613a06565b61106d565b34801561051a57600080fd5b50610376610529366004613a67565b600960209081526000928352604080842090915290825290205481565b34801561055257600080fd5b5061037660115481565b34801561056857600080fd5b506104766105773660046139e9565b600d602052600090815260409020546001600160a01b031681565b34801561059e57600080fd5b506104006105ad366004613a85565b611181565b3480156105be57600080fd5b506104006105cd366004613905565b61126f565b3480156105de57600080fd5b506104006105ed366004613905565b6113a2565b3480156105fe57600080fd5b5061040061060d366004613abe565b6114b9565b34801561061e57600080fd5b5061040061062d366004613afd565b6114e7565b34801561063e57600080fd5b5061040061064d3660046138d9565b6114fd565b34801561065e57600080fd5b5061040061066d366004613b29565b61151c565b34801561067e57600080fd5b5061040061068d366004613b95565b61157a565b34801561069e57600080fd5b506103766106ad366004613905565b600a6020526000908152604090205481565b3480156106cb57600080fd5b506103766106da366004613905565b61158f565b6104ae6106ed366004613bad565b611806565b3480156106fe57600080fd5b5061037660125481565b34801561071457600080fd5b5061071e61271081565b60405161ffff9091168152602001610380565b34801561073d57600080fd5b5061040061074c366004613bcf565b611acd565b34801561075d57600080fd5b50610400611b4c565b34801561077257600080fd5b50610376610781366004613bcf565b60086020526000908152604090205481565b34801561079f57600080fd5b50610400611c0b565b3480156107b457600080fd5b506104006107c3366004613bec565b611c1f565b6104006107d6366004613c38565b611c5a565b3480156107e757600080fd5b506104767f000000000000000000000000000000000000000000000000000000000000000081565b34801561081b57600080fd5b506000546001600160a01b0316610476565b34801561083957600080fd5b50602a5461071e9061ffff1681565b34801561085457600080fd5b5061037660035481565b34801561086a57600080fd5b506104ae610879366004613c5d565b611f36565b34801561088a57600080fd5b50610400610899366004613963565b612081565b6104006108ac366004613bad565b612112565b3480156108bd57600080fd5b5060025461071e9061ffff1681565b3480156108d857600080fd5b506108fc6108e7366004613905565b600b6020526000908152604090205460ff1681565b6040519015158152602001610380565b34801561091857600080fd5b5060025461071e9062010000900461ffff1681565b34801561093957600080fd5b50610400610948366004613963565b6121ec565b34801561095957600080fd5b506104767f000000000000000000000000000000000000000000000000000000000000000081565b34801561098d57600080fd5b50610376600f5481565b3480156109a357600080fd5b506103766109b2366004613905565b61233b565b3480156109c357600080fd5b5061037660055481565b3480156109d957600080fd5b5061037660065481565b3480156109ef57600080fd5b506104006109fe366004613bcf565b612352565b348015610a0f57600080fd5b50610400610a1e366004613905565b6123c8565b348015610a2f57600080fd5b506104767f000000000000000000000000000000000000000000000000000000000000000081565b348015610a6357600080fd5b5061037660045481565b348015610a7957600080fd5b50610a8d610a88366004613905565b6123d5565b6040516103809190613d0d565b348015610aa657600080fd5b50610400610ab5366004613df0565b6124d6565b348015610ac657600080fd5b50610376610ad53660046139e9565b600c6020526000908152604090205481565b610aef61253c565b6002805461ffff191661ffff92909216919091179055565b610b0f61253c565b80600c6000846003811115610b2657610b26613cf7565b6003811115610b3757610b37613cf7565b81526020810191909152604001600020555050565b600081601054610b5c9190613e24565b92915050565b60608160008167ffffffffffffffff811115610b8057610b80613e43565b604051908082528060200260200182016040528015610ba9578160200160208202803683370190505b50905060005b82811015610e3d576000868683818110610bcb57610bcb613e59565b602090810292909201356000818152600b9093526040909220549192505060ff1615610c3e5760405162461bcd60e51b815260206004820152601a60248201527f416d706c696669657220616c7265616479206d6967726174656400000000000060448201526064015b60405180910390fd5b604051631f3637cf60e31b8152600481018290526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f9b1be789060240161012060405180830381865afa158015610ca7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccb9190613ebd565b90508060400151600003610d215760405162461bcd60e51b815260206004820152601760248201527f416d706c696669657220646f65736e27742065786973740000000000000000006044820152606401610c35565b426003548260600151610d349190613f46565b1015610d795760405162461bcd60e51b815260206004820152601460248201527311dc9858d9481c195c9a5bd908195e1c1a5c995960621b6044820152606401610c35565b80602001516001600160a01b0316336001600160a01b031614610df35760405162461bcd60e51b815260206004820152602c60248201527f416d706c69666965722063616e206f6e6c79206265206d69677261746564206260448201526b3c903a34329036b4b73a32b960a11b6064820152608401610c35565b6000828152600b60205260409020805460ff19166001179055610e168183612596565b848481518110610e2857610e28613e59565b60209081029190910101525050600101610baf565b50949350505050565b6000600260015403610e6a5760405162461bcd60e51b8152600401610c3590613f59565b6002600155600f54600090610e7e84610b4c565b610e889190613f46565b9050803414610ea95760405162461bcd60e51b8152600401610c3590613f90565b600254336000908152600860205260409020546201000090910461ffff1611610f0a5760405162461bcd60e51b8152602060048201526013602482015272546f6f206d616e7920616d706c69666965727360681b6044820152606401610c35565b6012546040516390bca2fb60e01b815233600482015260248101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906390bca2fb906044016020604051808303816000875af1158015610f7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9f9190613fc7565b610fde5760405162461bcd60e51b815260206004820152601060248201526f2737ba1030b13632903a3790313ab93760811b6044820152606401610c35565b6000610fe9846128ba565b6028546040519192506000916001600160a01b039091169084908381818185875af1925050503d806000811461103b576040519150601f19603f3d011682016040523d82523d6000602084013e611040565b606091505b50509050806110615760405162461bcd60e51b8152600401610c3590613fe9565b50600180559392505050565b60026001540361108f5760405162461bcd60e51b8152600401610c3590613f59565b6002600155816000816110a184610b4c565b6110ab9190613e24565b90508034146110cc5760405162461bcd60e51b8152600401610c3590613f90565b60005b82811015611101576110f98686838181106110ec576110ec613e59565b9050602002013585612b03565b6001016110cf565b506028546040516000916001600160a01b03169083908381818185875af1925050503d806000811461114f576040519150601f19603f3d011682016040523d82523d6000602084013e611154565b606091505b50509050806111755760405162461bcd60e51b8152600401610c3590613fe9565b50506001805550505050565b61118961253c565b6040516370a0823160e01b81523060048201526001600160a01b0383169063a9059cbb90839083906370a0823190602401602060405180830381865afa1580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb9190614015565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015611246573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126a9190613fc7565b505050565b61127761253c565b60008181526007602090815260408083205461010090046001600160a01b031683526008825280832054848452600a909252909120548082146112fc5760008381526007602090815260408083205461010090046001600160a01b03168352600982528083208584528252808320548484528184208190558352600a90915290208190555b6000838152600a602090815260408083208390556007825280832080546001600160a01b036101009182900481168652600985528386208887528552838620869055915404168352600890915281208054916113578361402e565b90915550506006805490600061136c8361402e565b90915550505060009182525060076020526040902080546001600160e81b031916815560010180546001600160c01b0319169055565b6002600154036113c45760405162461bcd60e51b8152600401610c3590613f59565b600260015560006113d482612caa565b90506113df81612dd9565b60405163a9059cbb60e01b8152336004820152602481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303816000875af115801561144f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114739190613fc7565b61147c57600080fd5b60405181815233907f69cba1622d26658c0420d7e6b9b673716deaa320ceeac6aed1860ab4a6f601529060200160405180910390a2505060018055565b6114c161253c565b600f93909355601091909155601155602a805461ffff191661ffff909216919091179055565b6114ef61253c565b600392909255600455600555565b61150561253c565b80600e6000846003811115610b2657610b26613cf7565b60026001540361153e5760405162461bcd60e51b8152600401610c3590613f59565b60026001558260005b818110156111755761157286868381811061156457611564613e59565b905060200201358585613120565b600101611547565b61158261253c565b80602761126a8282614065565b60008181526007602052604080822081516101008101909252805483929190829060ff1660038111156115c4576115c4613cf7565b60038111156115d5576115d5613cf7565b815281546001600160a01b03610100820416602083015261ffff600160a81b8204811660408085019190915265ffffffffffff600160b81b909304831660608501526001909401548083166080850152600160301b8104831660a0850152600160601b8104831660c0850152600160901b900490911660e0909201919091529082015191925060009160149116101561168a576013826040015161ffff166014811061168357611683613e59565b01546116ab565b6013611698600160146140b2565b601481106116a8576116a8613e59565b01545b90506000816000846040015161ffff16116116ca5783608001516116d0565b83606001515b6116e29065ffffffffffff16426140b2565b6116ec9190613e24565b9050600454426116fc9190613f46565b836080015165ffffffffffff1610156117fe576000836080015165ffffffffffff166004544261172c9190613f46565b61173691906140b2565b905060646249d400821061174d57506103846117cd565b62409980821061176057506103206117cd565b62375f00821061177357506102bc6117cd565b622e2480821061178657506102586117cd565b6224ea00821061179957506101f46117cd565b621baf8082106117ac57506101906117cd565b6212750082106117bf575061012c6117cd565b62093a8082106117cd575060c85b60006117d98285613e24565b905060006117e98261271061350e565b91506117f7905081866140b2565b9450505050505b949350505050565b606060026001540361182a5760405162461bcd60e51b8152600401610c3590613f59565b6002600155600f54600090849061184085610b4c565b61184a9190613f46565b6118549190613e24565b90508034146118755760405162461bcd60e51b8152600401610c3590613f90565b600254336000908152600860205260409020546201000090910461ffff169061189f908690613f46565b11156118e35760405162461bcd60e51b8152602060048201526013602482015272546f6f206d616e7920616d706c69666965727360681b6044820152606401610c35565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166390bca2fb33866012546119219190613e24565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af115801561196c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119909190613fc7565b6119cf5760405162461bcd60e51b815260206004820152601060248201526f2737ba1030b13632903a3790313ab93760811b6044820152606401610c35565b8367ffffffffffffffff8111156119e8576119e8613e43565b604051908082528060200260200182016040528015611a11578160200160208202803683370190505b50915060005b84811015611a4d57611a28846128ba565b838281518110611a3a57611a3a613e59565b6020908102919091010152600101611a17565b506028546040516000916001600160a01b03169083908381818185875af1925050503d8060008114611a9b576040519150601f19603f3d011682016040523d82523d6000602084013e611aa0565b606091505b5050905080611ac15760405162461bcd60e51b8152600401610c3590613fe9565b50506001805592915050565b611ad561253c565b6000816001600160a01b03164760405160006040518083038185875af1925050503d8060008114611b22576040519150601f19603f3d011682016040523d82523d6000602084013e611b27565b606091505b5050905080611b485760405162461bcd60e51b8152600401610c3590613fe9565b5050565b611b5461253c565b60405163095ea7b360e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015260001960248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303816000875af1158015611be4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c089190613fc7565b50565b611c1361253c565b611c1d6000613542565b565b600260015403611c415760405162461bcd60e51b8152600401610c3590613f59565b6002600155611c51838383613120565b50506001805550565b600260015403611c7c5760405162461bcd60e51b8152600401610c3590613f59565b60026001556000828152600760205260409020805461010090046001600160a01b03163314611cbd5760405162461bcd60e51b8152600401610c35906140c5565b6000815460ff166003811115611cd557611cd5613cf7565b14611d125760405162461bcd60e51b815260206004820152600d60248201526c105b1c9958591e48199d5cd959609a1b6044820152606401610c35565b600181015442600160301b90910465ffffffffffff1611611d455760405162461bcd60e51b8152600401610c35906140f0565b6011543414611d665760405162461bcd60e51b8152600401610c3590613f90565b6000600d6000846003811115611d7e57611d7e613cf7565b6003811115611d8f57611d8f613cf7565b815260208101919091526040908101600020549051632967cf8360e21b8152600481018690526001600160a01b039091169063a59f3e0c906024016020604051808303816000875af1158015611de9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0d919061411b565b82549091508390839060ff19166001836003811115611e2e57611e2e613cf7565b021790555060018201805465ffffffffffff838116600160901b0265ffffffffffff60901b194292909216600160601b0291909116600160601b600160c01b031990921691909117179055826003811115611e8b57611e8b613cf7565b604051339086907fdf940f44a19932d19b1fa0f10b9c1246a8e1c5606636c480217c1759d65468d690600090a46028546040516000916001600160a01b03169034908381818185875af1925050503d8060008114611f05576040519150601f19603f3d011682016040523d82523d6000602084013e611f0a565b606091505b5050905080611f2b5760405162461bcd60e51b8152600401610c3590613fe9565b505060018055505050565b6060611f4061253c565b8584148015611f4e57508382145b611f905760405162461bcd60e51b815260206004820152601360248201527213195b99dd1a1cc81b9bdd08185b1a59db9959606a1b6044820152606401610c35565b858067ffffffffffffffff811115611faa57611faa613e43565b604051908082528060200260200182016040528015611fd3578160200160208202803683370190505b50915060005b8181101561207557612050898983818110611ff657611ff6613e59565b905060200201602081019061200b9190613bcf565b88888481811061201d5761201d613e59565b9050602002013587878581811061203657612036613e59565b905060200201602081019061204b91906139e9565b613592565b83828151811061206257612062613e59565b6020908102919091010152600101611fd9565b50509695505050505050565b61208961253c565b601481146120ca5760405162461bcd60e51b815260206004820152600e60248201526d092dcecc2d8d2c840d8cadccee8d60931b6044820152606401610c35565b8060005b8181101561210c578383828181106120e8576120e8613e59565b905060200201356013826014811061210257612102613e59565b01556001016120ce565b50505050565b6002600154036121345760405162461bcd60e51b8152600401610c3590613f59565b6002600155600061214482610b4c565b90508034146121655760405162461bcd60e51b8152600401610c3590613f90565b61216f8383612b03565b6028546040516000916001600160a01b03169083908381818185875af1925050503d80600081146121bc576040519150601f19603f3d011682016040523d82523d6000602084013e6121c1565b606091505b50509050806121e25760405162461bcd60e51b8152600401610c3590613fe9565b5050600180555050565b60026001540361220e5760405162461bcd60e51b8152600401610c3590613f59565b6002600155600081815b818110156122555761224185858381811061223557612235613e59565b90506020020135612caa565b61224b9084613f46565b9250600101612218565b5061225f82612dd9565b60405163a9059cbb60e01b8152336004820152602481018290529092507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303816000875af11580156122cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122f39190613fc7565b6122fc57600080fd5b60405182815233907f69cba1622d26658c0420d7e6b9b673716deaa320ceeac6aed1860ab4a6f601529060200160405180910390a25050600180555050565b6013816014811061234b57600080fd5b0154905081565b61235a61253c565b6001600160a01b0381166123bf5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c35565b611c0881613542565b6123d061253c565b601255565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915260008281526007602052604090819020815161010081019092528054829060ff16600381111561244857612448613cf7565b600381111561245957612459613cf7565b815281546001600160a01b03610100820416602083015261ffff600160a81b820416604083015265ffffffffffff600160b81b909104811660608301526001909201548083166080830152600160301b8104831660a0830152600160601b8104831660c0830152600160901b900490911660e09091015292915050565b6124de61253c565b80600d60008460038111156124f5576124f5613cf7565b600381111561250657612506613cf7565b815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055505050565b6000546001600160a01b03163314611c1d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c35565b600680546001810190915560408051610100810190915283516000929190819060038111156125c7576125c7613cf7565b815260200185602001516001600160a01b03168152602001856080015161ffff1681526020018560a0015165ffffffffffff168152602001856040015165ffffffffffff168152602001856060015165ffffffffffff1681526020018560c0015165ffffffffffff1681526020018560e0015165ffffffffffff168152506007600083815260200190815260200160002060008201518160000160006101000a81548160ff0219169083600381111561268257612682613cf7565b0217905550602082015181546040840151606085015165ffffffffffff908116600160b81b0265ffffffffffff60b81b1961ffff909316600160a81b0261ffff60a81b196001600160a01b039096166101000295909516610100600160b81b031990941693909317939093171617825560808301516001909201805460a085015160c086015160e0909601518416600160901b0265ffffffffffff60901b19968516600160601b0296909616600160601b600160c01b0319918516600160301b026001600160601b0319909316959094169490941717929092161791909117905560008451600381111561277857612778613cf7565b1461283257600d60008560000151600381111561279757612797613cf7565b60038111156127a8576127a8613cf7565b81526020810191909152604090810160009081205460e08701519251638c84c68360e01b81526004810185905265ffffffffffff909316602484015260448301919091526001600160a01b031690638c84c68390606401600060405180830381600087803b15801561281957600080fd5b505af115801561282d573d6000803e3d6000fd5b505050505b602080850180516001600160a01b039081166000908152600884526040808220805460018101909155845184168352600986528183208184528652818320879055868352600a909552808220859055925192519290911691849187917f12032246d9527ba32d0b656f176935871584cd8136c6c205e14e63ed379d9bb09190a4509392505050565b600080821180156128d1575060025461ffff168211155b6129125760405162461bcd60e51b81526020600482015260126024820152714d75737420626520312d36206d6f6e74687360701b6044820152606401610c35565b6006805460018101909155604080516101008101909152806000815233602082015260006040820181905260608201524265ffffffffffff16608082015260a0016129608562278d00613e24565b61296a9042613f46565b65ffffffffffff168152600060208083018290526040928301829052848252600790522081518154829060ff191660018360038111156129ac576129ac613cf7565b021790555060208281015182546040808601516060870151610100600160b81b03199093166101006001600160a01b039095169490940261ffff60a81b191693909317600160a81b61ffff909416939093029290921765ffffffffffff60b81b1916600160b81b65ffffffffffff9283160217845560808501516001948501805460a088015160c089015160e0909901519385166001600160601b031990921691909117600160301b9185169190910217600160601b600160c01b031916600160601b9784169790970265ffffffffffff60901b191696909617600160901b9190921602179093553360008181526008835284812080549485019055600983528481208482528352848120869055858152600a8352849020839055925186815291929184917f915b4bd5e5ec615d95d8794152a9d65ecb9d2244a84a094ffcbaca376f2a02fa910160405180910390a35092915050565b6000828152600760205260409020805461010090046001600160a01b03163314612b3f5760405162461bcd60e51b8152600401610c35906140c5565b60035460018201544291612b6191600160301b900465ffffffffffff16613f46565b1015612ba65760405162461bcd60e51b815260206004820152601460248201527311dc9858d9481c195c9a5bd908195e1c1a5c995960621b6044820152606401610c35565b612bb38262278d00613e24565b600182018054600690612bd6908490600160301b900465ffffffffffff16614143565b825465ffffffffffff9182166101009390930a928302919092021990911617905550600254612c0c9061ffff1662278d00614162565b612c1b9062ffffff1642613f46565b6001820154600160301b900465ffffffffffff1610612c6e5760405162461bcd60e51b815260206004820152600f60248201526e546f6f206d616e79206d6f6e74687360881b6044820152606401610c35565b604051828152339084907f5f2594387e270c9989f6a37982023109dbc9b27463e4ac9fd67d340b2fa207dd9060200160405180910390a3505050565b6000818152600760205260408120805461010090046001600160a01b03163314612ce65760405162461bcd60e51b8152600401610c35906140c5565b6000815460ff166003811115612cfe57612cfe613cf7565b14612d3d5760405162461bcd60e51b815260206004820152600f60248201526e135d5cdd081899481d5b999d5cd959608a1b6044820152606401610c35565b600181015442600160301b90910465ffffffffffff1611612d705760405162461bcd60e51b8152600401610c35906140f0565b612d798361158f565b8154909250600160a81b900461ffff16816015612d958361418d565b82546101009290920a61ffff81810219909316919092169190910217905550805465ffffffffffff60b81b1916600160b81b4265ffffffffffff1602179055919050565b602a54600090819061271090612df39061ffff1685613e24565b612dfd91906141c4565b60408051600280825260608201835292935060009290916020830190803683370190505090507f000000000000000000000000000000000000000000000000000000000000000081600081518110612e5757612e57613e59565b60200260200101906001600160a01b031690816001600160a01b0316815250507f000000000000000000000000000000000000000000000000000000000000000081600181518110612eab57612eab613e59565b6001600160a01b039283166020918202929092010152604051635c11d79560e01b81527f000000000000000000000000000000000000000000000000000000000000000090911690635c11d79590612f109085906000908690309042906004016141e6565b600060405180830381600087803b158015612f2a57600080fd5b505af1158015612f3e573d6000803e3d6000fd5b50506040516370a0823160e01b815230600482015260009250600291506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015612fac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd09190614015565b612fda91906141c4565b60275460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529192507f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303816000875af115801561304f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130739190613fc7565b5060295460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303816000875af11580156130e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061310c9190613fc7565b5061311783866140b2565b95945050505050565b600083815260076020526040812090815460ff16600381111561314557613145613cf7565b036131825760405162461bcd60e51b815260206004820152600d60248201526c135d5cdd08189948199d5cd959609a1b6044820152606401610c35565b60055460018201546131a390600160601b900465ffffffffffff16426140b2565b116131e75760405162461bcd60e51b815260206004820152601460248201527310d85b9b9bdd0818db185a5b48115512081e595d60621b6044820152606401610c35565b811561332a57600181015442600160301b90910465ffffffffffff16116132205760405162461bcd60e51b8152600401610c35906140f0565b8054600090600d90829060ff16600381111561323e5761323e613cf7565b600381111561324f5761324f613cf7565b8152602081019190915260409081016000205490516358db332960e11b81526001600160a01b039091169063b1b666529061329290889088908890600401614257565b6020604051808303816000875af11580156132b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d59190614015565b825460405191925033916101009091046001600160a01b03169087907fa924a34e4fc8eaee5b8cfa925b99aaf25c8e7604b64548958dce31a5e23b695b906133209086815260200190565b60405180910390a4505b600181015442600160901b90910465ffffffffffff161161210c57600181015442600160301b90910465ffffffffffff1611156134535780546001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169163a9059cbb9161010082041690600e9060009060ff1660038111156133b6576133b6613cf7565b60038111156133c7576133c7613cf7565b8152602001908152602001600020546040518363ffffffff1660e01b81526004016134079291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015613426573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061344a9190613fc7565b61345357600080fd5b8054600d9060009060ff16600381111561346f5761346f613cf7565b600381111561348057613480613cf7565b815260208101919091526040908101600020549051637f8661a160e01b8152600481018690526001600160a01b0390911690637f8661a190602401600060405180830381600087803b1580156134d557600080fd5b505af11580156134e9573d6000803e3d6000fd5b5050825460ff1916835550506001018054600160601b600160c01b0319169055505050565b600080826000036135245750600090508061353b565b6001838581613535576135356141ae565b04915091505b9250929050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60025460009061ffff168311156135dd5760405162461bcd60e51b815260206004820152600f60248201526e546f6f206d616e79206d6f6e74687360881b6044820152606401610c35565b6006805460018082019092556001600160a01b038616600090815260086020526040812080549384019055909190808086600381111561361f5761361f613cf7565b146136cf57429150600d600087600381111561363d5761363d613cf7565b600381111561364e5761364e613cf7565b815260208101919091526040908101600020549051632967cf8360e21b8152600481018690526001600160a01b039091169063a59f3e0c906024016020604051808303816000875af11580156136a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136cc919061411b565b90505b6040518061010001604052808760038111156136ed576136ed613cf7565b81526001600160a01b038a16602082015260006040820181905260608201524265ffffffffffff16608082015260a00161372a8962278d00613e24565b6137349042613f46565b65ffffffffffff9081168252848116602080840191909152908416604092830152600087815260079091522081518154829060ff1916600183600381111561377e5761377e613cf7565b021790555060208281015182546040808601516060870151610100600160b81b03199093166101006001600160a01b039586160261ffff60a81b191617600160a81b61ffff909216919091021765ffffffffffff60b81b1916600160b81b65ffffffffffff9384160217855560808601516001909501805460a088015160c089015160e0909901519785166001600160601b031990921691909117600160301b9185169190910217600160601b600160c01b031916600160601b9784169790970265ffffffffffff60901b191696909617600160901b95909216949094021790935599909116600090815260098a528181208582528a52818120869055858152600a9099529097209190915550949350505050565b803561ffff811681146138a557600080fd5b919050565b6000602082840312156138bc57600080fd5b6138c582613893565b9392505050565b60048110611c0857600080fd5b600080604083850312156138ec57600080fd5b82356138f7816138cc565b946020939093013593505050565b60006020828403121561391757600080fd5b5035919050565b60008083601f84011261393057600080fd5b50813567ffffffffffffffff81111561394857600080fd5b6020830191508360208260051b850101111561353b57600080fd5b6000806020838503121561397657600080fd5b823567ffffffffffffffff81111561398d57600080fd5b6139998582860161391e565b90969095509350505050565b6020808252825182820181905260009190848201906040850190845b818110156139dd578351835292840192918401916001016139c1565b50909695505050505050565b6000602082840312156139fb57600080fd5b81356138c5816138cc565b600080600060408486031215613a1b57600080fd5b833567ffffffffffffffff811115613a3257600080fd5b613a3e8682870161391e565b909790965060209590950135949350505050565b6001600160a01b0381168114611c0857600080fd5b60008060408385031215613a7a57600080fd5b82356138f781613a52565b60008060408385031215613a9857600080fd5b8235613aa381613a52565b91506020830135613ab381613a52565b809150509250929050565b60008060008060808587031215613ad457600080fd5b843593506020850135925060408501359150613af260608601613893565b905092959194509250565b600080600060608486031215613b1257600080fd5b505081359360208301359350604090920135919050565b60008060008060408587031215613b3f57600080fd5b843567ffffffffffffffff80821115613b5757600080fd5b613b638883890161391e565b90965094506020870135915080821115613b7c57600080fd5b50613b898782880161391e565b95989497509550505050565b600060608284031215613ba757600080fd5b50919050565b60008060408385031215613bc057600080fd5b50508035926020909101359150565b600060208284031215613be157600080fd5b81356138c581613a52565b600080600060408486031215613c0157600080fd5b83359250602084013567ffffffffffffffff811115613c1f57600080fd5b613c2b8682870161391e565b9497909650939450505050565b60008060408385031215613c4b57600080fd5b823591506020830135613ab3816138cc565b60008060008060008060608789031215613c7657600080fd5b863567ffffffffffffffff80821115613c8e57600080fd5b613c9a8a838b0161391e565b90985096506020890135915080821115613cb357600080fd5b613cbf8a838b0161391e565b90965094506040890135915080821115613cd857600080fd5b50613ce589828a0161391e565b979a9699509497509295939492505050565b634e487b7160e01b600052602160045260246000fd5b815161010082019060048110613d3357634e487b7160e01b600052602160045260246000fd5b808352506020830151613d5160208401826001600160a01b03169052565b506040830151613d67604084018261ffff169052565b506060830151613d81606084018265ffffffffffff169052565b506080830151613d9b608084018265ffffffffffff169052565b5060a0830151613db560a084018265ffffffffffff169052565b5060c0830151613dcf60c084018265ffffffffffff169052565b5060e0830151613de960e084018265ffffffffffff169052565b5092915050565b60008060408385031215613e0357600080fd5b8235613aa3816138cc565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615613e3e57613e3e613e0e565b500290565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b604051610120810167ffffffffffffffff81118282101715613ea157634e487b7160e01b600052604160045260246000fd5b60405290565b80516138a5816138cc565b80516138a581613a52565b60006101208284031215613ed057600080fd5b613ed8613e6f565b613ee183613ea7565b8152613eef60208401613eb2565b602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152508091505092915050565b80820180821115610b5c57610b5c613e0e565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252601c908201527f496e76616c69642045746865722076616c75652070726f766964656400000000604082015260600190565b600060208284031215613fd957600080fd5b815180151581146138c557600080fd5b602080825260129082015271086deead8c840dcdee840e6cadcc8408aa8960731b604082015260600190565b60006020828403121561402757600080fd5b5051919050565b60008161403d5761403d613e0e565b506000190190565b80546001600160a01b0319166001600160a01b0392909216919091179055565b813561407081613a52565b61407a8183614045565b50602082013561408981613a52565b6140968160018401614045565b5060408201356140a581613a52565b61126a8160028401614045565b81810381811115610b5c57610b5c613e0e565b6020808252601190820152700496e76616c6964206f776e65727368697607c1b604082015260600190565b602080825260119082015270105b5c1b1a599a595c88195e1c1a5c9959607a1b604082015260600190565b60006020828403121561412d57600080fd5b815165ffffffffffff811681146138c557600080fd5b65ffffffffffff818116838216019080821115613de957613de9613e0e565b600062ffffff8083168185168183048111821515161561418457614184613e0e565b02949350505050565b600061ffff8083168181036141a4576141a4613e0e565b6001019392505050565b634e487b7160e01b600052601260045260246000fd5b6000826141e157634e487b7160e01b600052601260045260246000fd5b500490565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b818110156142365784516001600160a01b031683529383019391830191600101614211565b50506001600160a01b03969096166060850152505050608001529392505050565b838152604060208201819052810182905260006001600160fb1b0383111561427e57600080fd5b8260051b808560608501379190910160600194935050505056fea26469706673582212206a6a1cff86d1f491782e476233bc317274211f6105a240f471a02298a82e884a64736f6c6343000810003360a06040523480156200001157600080fd5b5060405162001937380380620019378339810160408190526200003491620000de565b6200003f3362000075565b6200004a8362000075565b600180546001600160a01b0319166001600160a01b0393909316929092179091556080525062000126565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0381168114620000db57600080fd5b50565b600080600060608486031215620000f457600080fd5b83516200010181620000c5565b60208501519093506200011481620000c5565b80925050604084015190509250925092565b6080516117f5620001426000396000610b4701526117f56000f3fe60806040526004361061011f5760003560e01c80638c84c683116100a0578063a59f3e0c11610064578063a59f3e0c14610383578063b1b66652146103ba578063bbc77eac146103da578063d885a21e146103fa578063f2fde38b1461040257600080fd5b80638c84c683146102d15780638da5cb5b146102f15780638e539e8c1461032357806398b1c261146103435780639dc5c7461461036357600080fd5b80634ba2363a116100e75780634ba2363a14610229578063690d8320146102315780636cb7372114610251578063715018a61461029c5780637f8661a1146102b157600080fd5b80631251b6ab1461012457806318160ddd1461016457806323724e351461017a578063359a5f7f1461019a5780633aeac4e114610207575b600080fd5b34801561013057600080fd5b5061015161013f366004611326565b60046020526000908152604090205481565b6040519081526020015b60405180910390f35b34801561017057600080fd5b5061015160055481565b34801561018657600080fd5b506101516101953660046113b0565b610422565b3480156101a657600080fd5b506101e16101b5366004611326565b60036020526000908152604090205465ffffffffffff811690600160301b90046001600160d01b031682565b6040805165ffffffffffff90931683526001600160d01b0390911660208301520161015b565b34801561021357600080fd5b50610227610222366004611471565b6104d9565b005b6102276105c7565b34801561023d57600080fd5b5061022761024c3660046114aa565b61066c565b34801561025d57600080fd5b5061028c61026c3660046114c7565b600260209081526000928352604080842090915290825290205460ff1681565b604051901515815260200161015b565b3480156102a857600080fd5b50610227610715565b3480156102bd57600080fd5b506102276102cc366004611326565b610729565b3480156102dd57600080fd5b506102276102ec36600461150b565b610831565b3480156102fd57600080fd5b506000546001600160a01b03165b6040516001600160a01b03909116815260200161015b565b34801561032f57600080fd5b5061015161033e366004611326565b610941565b34801561034f57600080fd5b5061015161035e3660046114c7565b610993565b34801561036f57600080fd5b5061015161037e3660046114c7565b6109f9565b34801561038f57600080fd5b506103a361039e366004611326565b610a41565b60405165ffffffffffff909116815260200161015b565b3480156103c657600080fd5b506101516103d536600461154d565b610b85565b3480156103e657600080fd5b5060015461030b906001600160a01b031681565b610227610c61565b34801561040e57600080fd5b5061022761041d3660046114aa565b610c69565b600080805b84518110156104cf576000858281518110610444576104446115cc565b6020908102919091018101516000878152600283526040808220838352909352919091205490915060ff166104c65761047c81610941565b600082815260036020526040902054600160301b90046001600160d01b03166104a58784610993565b6104af91906115f8565b6104b99190611617565b6104c39084611639565b92505b50600101610427565b5090505b92915050565b6104e1610ce2565b6040516370a0823160e01b81523060048201526001600160a01b0383169063a9059cbb90839083906370a0823190602401602060405180830381865afa15801561052f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610553919061164c565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af115801561059e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c29190611665565b505050565b6105cf610ce2565b60405180604001604052804265ffffffffffff1681526020016105f134610d3c565b6001600160d01b039081169091524360009081526003602090815260409182902084519490910151909216600160301b0265ffffffffffff909316929092179055517f54390daa7a4eaa8ded41401c920f8ae34737125099853ad55d28699819f2596b906106629034815260200190565b60405180910390a1565b610674610ce2565b6000816001600160a01b03164760405160006040518083038185875af1925050503d80600081146106c1576040519150601f19603f3d011682016040523d82523d6000602084013e6106c6565b606091505b50509050806107115760405162461bcd60e51b8152602060048201526012602482015271086deead8c840dcdee840e6cadcc8408aa8960731b60448201526064015b60405180910390fd5b5050565b61071d610ce2565b6107276000610da9565b565b6001546001600160a01b031633146107535760405162461bcd60e51b815260040161070890611682565b6000818152600460205260409020544210156107a35760405162461bcd60e51b815260206004820152600f60248201526e10d85b9b9bdd08195e1a5d081e595d608a1b6044820152606401610708565b6000818152600660209081526040808320815180830190925263ffffffff438116835282840185815282546001818101855593875294909520925194516001600160e01b03166401000000000294169390931791015561080990600790610df990610e05565b50506005805490600061081b836116aa565b9091555050600090815260046020526040812055565b6001546001600160a01b0316331461085b5760405162461bcd60e51b815260040161070890611682565b60008381526004602052604090205415806108735750805b6108b65760405162461bcd60e51b8152602060048201526014602482015273536861726520616c72656164792065786973747360601b6044820152606401610708565b60008381526006602090815260408083208151808301835263ffffffff4381168252600182860181815284548083018655948852868820935190516001600160e01b0316640100000000029216919091179190920155868452600490925290912065ffffffffffff84169055600580548201905561093a90600790610f7690610e05565b5050505050565b60004382106109885760405162461bcd60e51b8152602060048201526013602482015272189b1bd8dac81b9bdd081e595d081b5a5b9959606a1b6044820152606401610708565b6104d3600783610f82565b60004382106109da5760405162461bcd60e51b8152602060048201526013602482015272189b1bd8dac81b9bdd081e595d081b5a5b9959606a1b6044820152606401610708565b60008381526006602052604090206109f29083610f82565b9392505050565b6000610a0483610941565b600084815260036020526040902054600160301b90046001600160d01b0316610a2d8486610993565b610a3791906115f8565b6109f29190611617565b6001546000906001600160a01b03163314610a6e5760405162461bcd60e51b815260040161070890611682565b60008281526004602052604090205415610ac15760405162461bcd60e51b8152602060048201526014602482015273536861726520616c72656164792065786973747360601b6044820152606401610708565b6000828152600660209081526040808320815180830190925263ffffffff438116835260018385018181528354808301855593875294909520925193516001600160e01b031664010000000002931692909217910155610b2790600790610f7690610e05565b505060058054906000610b39836116c1565b9091555060009050610b6b427f0000000000000000000000000000000000000000000000000000000000000000611639565b60008481526004602052604090208190559150505b919050565b6001546000906001600160a01b03163314610bb25760405162461bcd60e51b815260040161070890611682565b600082815b81811015610c4d576000610be3878784818110610bd657610bd66115cc565b905060200201358961103f565b9050868683818110610bf757610bf76115cc565b90506020020135887fd16b1baf5a6367aef04997ff7695583fd3c7b775ba5d24a74c7ae3f33582f32c83604051610c3091815260200190565b60405180910390a3610c428185611639565b935050600101610bb7565b50610c58828761114c565b50949350505050565b610727610ce2565b610c71610ce2565b6001600160a01b038116610cd65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610708565b610cdf81610da9565b50565b6000546001600160a01b031633146107275760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610708565b60006001600160d01b03821115610da55760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663038206269747360c81b6064820152608401610708565b5090565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006109f282846116da565b825460009081908015610e505785610e1e6001836116da565b81548110610e2e57610e2e6115cc565b60009182526020909120015464010000000090046001600160e01b0316610e53565b60005b6001600160e01b03169250610e6c83858763ffffffff16565b9150600081118015610eaa57504386610e866001846116da565b81548110610e9657610e966115cc565b60009182526020909120015463ffffffff16145b15610f0a57610eb8826112a2565b86610ec46001846116da565b81548110610ed457610ed46115cc565b9060005260206000200160000160046101000a8154816001600160e01b0302191690836001600160e01b03160217905550610f6d565b8560405180604001604052804363ffffffff168152602001610f2b856112a2565b6001600160e01b0390811690915282546001810184556000938452602093849020835194909301519091166401000000000263ffffffff909316929092179101555b50935093915050565b60006109f28284611639565b8154600090815b81811015610fe6576000610f9d828461130b565b905084868281548110610fb257610fb26115cc565b60009182526020909120015463ffffffff161115610fd257809250610fe0565b610fdd816001611639565b91505b50610f89565b811561102a5784610ff86001846116da565b81548110611008576110086115cc565b60009182526020909120015464010000000090046001600160e01b031661102d565b60005b6001600160e01b031695945050505050565b600081815260026020908152604080832085845290915281205460ff16156110a95760405162461bcd60e51b815260206004820152601c60248201527f416c726561647920636c61696d696564207468697320706572696f64000000006044820152606401610708565b60008381526003602090815260408083205485845260049092529091205465ffffffffffff9091161061111e5760405162461bcd60e51b815260206004820152601860248201527f506572696f6420616674657220756e6c6f636b2074696d6500000000000000006044820152606401610708565b60008281526002602090815260408083208684529091529020805460ff191660011790556109f283836109f9565b6000821161118f5760405162461bcd60e51b815260206004820152601060248201526f4e6f2045544820636c61696d61626c6560801b6044820152606401610708565b600154604051631f3637cf60e31b8152600481018390526000916001600160a01b03169063f9b1be789060240161010060405180830381865afa1580156111da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fe9190611715565b9050600081602001516001600160a01b03168460405160006040518083038185875af1925050503d8060008114611251576040519150601f19603f3d011682016040523d82523d6000602084013e611256565b606091505b505090508061129c5760405162461bcd60e51b8152602060048201526012602482015271086deead8c840dcdee840e6cadcc8408aa8960731b6044820152606401610708565b50505050565b60006001600160e01b03821115610da55760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b6064820152608401610708565b600061131a6002848418611617565b6109f290848416611639565b60006020828403121561133857600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051610100810167ffffffffffffffff811182821017156113795761137961133f565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156113a8576113a861133f565b604052919050565b600080604083850312156113c357600080fd5b823567ffffffffffffffff808211156113db57600080fd5b818501915085601f8301126113ef57600080fd5b81356020828211156114035761140361133f565b8160051b925061141481840161137f565b828152928401810192818101908985111561142e57600080fd5b948201945b8486101561144c57853582529482019490820190611433565b9997909101359750505050505050565b6001600160a01b0381168114610cdf57600080fd5b6000806040838503121561148457600080fd5b823561148f8161145c565b9150602083013561149f8161145c565b809150509250929050565b6000602082840312156114bc57600080fd5b81356109f28161145c565b600080604083850312156114da57600080fd5b50508035926020909101359150565b65ffffffffffff81168114610cdf57600080fd5b8015158114610cdf57600080fd5b60008060006060848603121561152057600080fd5b833592506020840135611532816114e9565b91506040840135611542816114fd565b809150509250925092565b60008060006040848603121561156257600080fd5b83359250602084013567ffffffffffffffff8082111561158157600080fd5b818601915086601f83011261159557600080fd5b8135818111156115a457600080fd5b8760208260051b85010111156115b957600080fd5b6020830194508093505050509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615611612576116126115e2565b500290565b60008261163457634e487b7160e01b600052601260045260246000fd5b500490565b808201808211156104d3576104d36115e2565b60006020828403121561165e57600080fd5b5051919050565b60006020828403121561167757600080fd5b81516109f2816114fd565b6020808252600e908201526d27b7363c9020b6b83634b334b2b960911b604082015260600190565b6000816116b9576116b96115e2565b506000190190565b6000600182016116d3576116d36115e2565b5060010190565b818103818111156104d3576104d36115e2565b8051610b808161145c565b805161ffff81168114610b8057600080fd5b8051610b80816114e9565b6000610100828403121561172857600080fd5b611730611355565b82516004811061173f57600080fd5b815261174d602084016116ed565b602082015261175e604084016116f8565b604082015261176f6060840161170a565b60608201526117806080840161170a565b608082015261179160a0840161170a565b60a08201526117a260c0840161170a565b60c08201526117b360e0840161170a565b60e0820152939250505056fea26469706673582212203fc091721718ed175db3c0fd55402261e781f4cb3605feee6f1d1a485656d6c364736f6c63430008100033000000000000000000000000d23367155b55d67492dfdc0fc7f8bb1df7114fd90000000000000000000000004b81d30d621e8a22ca6016ec8053e3dfaa3d5edf0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Deployed Bytecode
0x6080604052600436106103545760003560e01c80636991b45c116101c6578063bbb7a429116100f7578063f2fde38b11610095578063f98d4a881161006f578063f98d4a8814610a57578063f9b1be7814610a6d578063fa8711aa14610a9a578063fe0e6ee914610aba57600080fd5b8063f2fde38b146109e3578063f4a0a52814610a03578063f887ea4014610a2357600080fd5b8063dce0b4e4116100d1578063dce0b4e414610981578063dd418ae214610997578063de1f0713146109b7578063ed8c5e83146109cd57600080fd5b8063bbb7a4291461090c578063c71fcd271461092d578063d904ecd91461094d57600080fd5b806399d32fc411610164578063ab98f4ae1161013e578063ab98f4ae1461087e578063ac597cb21461089e578063b6ed9d6f146108b1578063b72fc876146108cc57600080fd5b806399d32fc41461082d578063a06db7dc14610848578063a3a742d51461085e57600080fd5b806378fdb555116101a057806378fdb555146107a85780637eed4a39146107c857806389a30271146107db5780638da5cb5b1461080f57600080fd5b80636991b45c1461075157806370a0823114610766578063715018a61461079357600080fd5b80633aeac4e1116102a05780634c20f90a1161023e578063601ea33111610218578063601ea331146106df5780636817c76c146106f25780636823732914610708578063690d83201461073157600080fd5b80634c20f90a146106725780635bf3df4e146106925780635f8ee864146106bf57600080fd5b80633f0609b41161027a5780633f0609b4146105f2578063417314591461061257806343840c52146106325780634b9497b21461065257600080fd5b80633aeac4e1146105925780633b973802146105b25780633db59093146105d257600080fd5b80631267a00a1161030d57806325627b54116102e757806325627b54146104fb5780632f346b691461050e57806332d4268a14610546578063388fdd0c1461055c57600080fd5b80631267a00a1461048e57806317b2e40a146104bb578063208e831a146104e857600080fd5b8063080b301e146103605780630adfdcb9146103895780630cf4680e146103e05780630d06279e146104025780630f3ac4a31461042257806310909c7d1461044257600080fd5b3661035b57005b600080fd5b34801561036c57600080fd5b5061037660105481565b6040519081526020015b60405180910390f35b34801561039557600080fd5b506027546028546029546103b6926001600160a01b03908116928116911683565b604080516001600160a01b0394851681529284166020840152921691810191909152606001610380565b3480156103ec57600080fd5b506104006103fb3660046138aa565b610ae7565b005b34801561040e57600080fd5b5061040061041d3660046138d9565b610b07565b34801561042e57600080fd5b5061037661043d366004613905565b610b4c565b34801561044e57600080fd5b506104767f0000000000000000000000004b81d30d621e8a22ca6016ec8053e3dfaa3d5edf81565b6040516001600160a01b039091168152602001610380565b34801561049a57600080fd5b506104ae6104a9366004613963565b610b62565b60405161038091906139a5565b3480156104c757600080fd5b506103766104d63660046139e9565b600e6020526000908152604090205481565b6103766104f6366004613905565b610e46565b610400610509366004613a06565b61106d565b34801561051a57600080fd5b50610376610529366004613a67565b600960209081526000928352604080842090915290825290205481565b34801561055257600080fd5b5061037660115481565b34801561056857600080fd5b506104766105773660046139e9565b600d602052600090815260409020546001600160a01b031681565b34801561059e57600080fd5b506104006105ad366004613a85565b611181565b3480156105be57600080fd5b506104006105cd366004613905565b61126f565b3480156105de57600080fd5b506104006105ed366004613905565b6113a2565b3480156105fe57600080fd5b5061040061060d366004613abe565b6114b9565b34801561061e57600080fd5b5061040061062d366004613afd565b6114e7565b34801561063e57600080fd5b5061040061064d3660046138d9565b6114fd565b34801561065e57600080fd5b5061040061066d366004613b29565b61151c565b34801561067e57600080fd5b5061040061068d366004613b95565b61157a565b34801561069e57600080fd5b506103766106ad366004613905565b600a6020526000908152604090205481565b3480156106cb57600080fd5b506103766106da366004613905565b61158f565b6104ae6106ed366004613bad565b611806565b3480156106fe57600080fd5b5061037660125481565b34801561071457600080fd5b5061071e61271081565b60405161ffff9091168152602001610380565b34801561073d57600080fd5b5061040061074c366004613bcf565b611acd565b34801561075d57600080fd5b50610400611b4c565b34801561077257600080fd5b50610376610781366004613bcf565b60086020526000908152604090205481565b34801561079f57600080fd5b50610400611c0b565b3480156107b457600080fd5b506104006107c3366004613bec565b611c1f565b6104006107d6366004613c38565b611c5a565b3480156107e757600080fd5b506104767f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b34801561081b57600080fd5b506000546001600160a01b0316610476565b34801561083957600080fd5b50602a5461071e9061ffff1681565b34801561085457600080fd5b5061037660035481565b34801561086a57600080fd5b506104ae610879366004613c5d565b611f36565b34801561088a57600080fd5b50610400610899366004613963565b612081565b6104006108ac366004613bad565b612112565b3480156108bd57600080fd5b5060025461071e9061ffff1681565b3480156108d857600080fd5b506108fc6108e7366004613905565b600b6020526000908152604090205460ff1681565b6040519015158152602001610380565b34801561091857600080fd5b5060025461071e9062010000900461ffff1681565b34801561093957600080fd5b50610400610948366004613963565b6121ec565b34801561095957600080fd5b506104767f000000000000000000000000d23367155b55d67492dfdc0fc7f8bb1df7114fd981565b34801561098d57600080fd5b50610376600f5481565b3480156109a357600080fd5b506103766109b2366004613905565b61233b565b3480156109c357600080fd5b5061037660055481565b3480156109d957600080fd5b5061037660065481565b3480156109ef57600080fd5b506104006109fe366004613bcf565b612352565b348015610a0f57600080fd5b50610400610a1e366004613905565b6123c8565b348015610a2f57600080fd5b506104767f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d81565b348015610a6357600080fd5b5061037660045481565b348015610a7957600080fd5b50610a8d610a88366004613905565b6123d5565b6040516103809190613d0d565b348015610aa657600080fd5b50610400610ab5366004613df0565b6124d6565b348015610ac657600080fd5b50610376610ad53660046139e9565b600c6020526000908152604090205481565b610aef61253c565b6002805461ffff191661ffff92909216919091179055565b610b0f61253c565b80600c6000846003811115610b2657610b26613cf7565b6003811115610b3757610b37613cf7565b81526020810191909152604001600020555050565b600081601054610b5c9190613e24565b92915050565b60608160008167ffffffffffffffff811115610b8057610b80613e43565b604051908082528060200260200182016040528015610ba9578160200160208202803683370190505b50905060005b82811015610e3d576000868683818110610bcb57610bcb613e59565b602090810292909201356000818152600b9093526040909220549192505060ff1615610c3e5760405162461bcd60e51b815260206004820152601a60248201527f416d706c696669657220616c7265616479206d6967726174656400000000000060448201526064015b60405180910390fd5b604051631f3637cf60e31b8152600481018290526000907f0000000000000000000000004b81d30d621e8a22ca6016ec8053e3dfaa3d5edf6001600160a01b03169063f9b1be789060240161012060405180830381865afa158015610ca7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccb9190613ebd565b90508060400151600003610d215760405162461bcd60e51b815260206004820152601760248201527f416d706c696669657220646f65736e27742065786973740000000000000000006044820152606401610c35565b426003548260600151610d349190613f46565b1015610d795760405162461bcd60e51b815260206004820152601460248201527311dc9858d9481c195c9a5bd908195e1c1a5c995960621b6044820152606401610c35565b80602001516001600160a01b0316336001600160a01b031614610df35760405162461bcd60e51b815260206004820152602c60248201527f416d706c69666965722063616e206f6e6c79206265206d69677261746564206260448201526b3c903a34329036b4b73a32b960a11b6064820152608401610c35565b6000828152600b60205260409020805460ff19166001179055610e168183612596565b848481518110610e2857610e28613e59565b60209081029190910101525050600101610baf565b50949350505050565b6000600260015403610e6a5760405162461bcd60e51b8152600401610c3590613f59565b6002600155600f54600090610e7e84610b4c565b610e889190613f46565b9050803414610ea95760405162461bcd60e51b8152600401610c3590613f90565b600254336000908152600860205260409020546201000090910461ffff1611610f0a5760405162461bcd60e51b8152602060048201526013602482015272546f6f206d616e7920616d706c69666965727360681b6044820152606401610c35565b6012546040516390bca2fb60e01b815233600482015260248101919091527f000000000000000000000000d23367155b55d67492dfdc0fc7f8bb1df7114fd96001600160a01b0316906390bca2fb906044016020604051808303816000875af1158015610f7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9f9190613fc7565b610fde5760405162461bcd60e51b815260206004820152601060248201526f2737ba1030b13632903a3790313ab93760811b6044820152606401610c35565b6000610fe9846128ba565b6028546040519192506000916001600160a01b039091169084908381818185875af1925050503d806000811461103b576040519150601f19603f3d011682016040523d82523d6000602084013e611040565b606091505b50509050806110615760405162461bcd60e51b8152600401610c3590613fe9565b50600180559392505050565b60026001540361108f5760405162461bcd60e51b8152600401610c3590613f59565b6002600155816000816110a184610b4c565b6110ab9190613e24565b90508034146110cc5760405162461bcd60e51b8152600401610c3590613f90565b60005b82811015611101576110f98686838181106110ec576110ec613e59565b9050602002013585612b03565b6001016110cf565b506028546040516000916001600160a01b03169083908381818185875af1925050503d806000811461114f576040519150601f19603f3d011682016040523d82523d6000602084013e611154565b606091505b50509050806111755760405162461bcd60e51b8152600401610c3590613fe9565b50506001805550505050565b61118961253c565b6040516370a0823160e01b81523060048201526001600160a01b0383169063a9059cbb90839083906370a0823190602401602060405180830381865afa1580156111d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fb9190614015565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015611246573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126a9190613fc7565b505050565b61127761253c565b60008181526007602090815260408083205461010090046001600160a01b031683526008825280832054848452600a909252909120548082146112fc5760008381526007602090815260408083205461010090046001600160a01b03168352600982528083208584528252808320548484528184208190558352600a90915290208190555b6000838152600a602090815260408083208390556007825280832080546001600160a01b036101009182900481168652600985528386208887528552838620869055915404168352600890915281208054916113578361402e565b90915550506006805490600061136c8361402e565b90915550505060009182525060076020526040902080546001600160e81b031916815560010180546001600160c01b0319169055565b6002600154036113c45760405162461bcd60e51b8152600401610c3590613f59565b600260015560006113d482612caa565b90506113df81612dd9565b60405163a9059cbb60e01b8152336004820152602481018290529091507f000000000000000000000000d23367155b55d67492dfdc0fc7f8bb1df7114fd96001600160a01b03169063a9059cbb906044016020604051808303816000875af115801561144f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114739190613fc7565b61147c57600080fd5b60405181815233907f69cba1622d26658c0420d7e6b9b673716deaa320ceeac6aed1860ab4a6f601529060200160405180910390a2505060018055565b6114c161253c565b600f93909355601091909155601155602a805461ffff191661ffff909216919091179055565b6114ef61253c565b600392909255600455600555565b61150561253c565b80600e6000846003811115610b2657610b26613cf7565b60026001540361153e5760405162461bcd60e51b8152600401610c3590613f59565b60026001558260005b818110156111755761157286868381811061156457611564613e59565b905060200201358585613120565b600101611547565b61158261253c565b80602761126a8282614065565b60008181526007602052604080822081516101008101909252805483929190829060ff1660038111156115c4576115c4613cf7565b60038111156115d5576115d5613cf7565b815281546001600160a01b03610100820416602083015261ffff600160a81b8204811660408085019190915265ffffffffffff600160b81b909304831660608501526001909401548083166080850152600160301b8104831660a0850152600160601b8104831660c0850152600160901b900490911660e0909201919091529082015191925060009160149116101561168a576013826040015161ffff166014811061168357611683613e59565b01546116ab565b6013611698600160146140b2565b601481106116a8576116a8613e59565b01545b90506000816000846040015161ffff16116116ca5783608001516116d0565b83606001515b6116e29065ffffffffffff16426140b2565b6116ec9190613e24565b9050600454426116fc9190613f46565b836080015165ffffffffffff1610156117fe576000836080015165ffffffffffff166004544261172c9190613f46565b61173691906140b2565b905060646249d400821061174d57506103846117cd565b62409980821061176057506103206117cd565b62375f00821061177357506102bc6117cd565b622e2480821061178657506102586117cd565b6224ea00821061179957506101f46117cd565b621baf8082106117ac57506101906117cd565b6212750082106117bf575061012c6117cd565b62093a8082106117cd575060c85b60006117d98285613e24565b905060006117e98261271061350e565b91506117f7905081866140b2565b9450505050505b949350505050565b606060026001540361182a5760405162461bcd60e51b8152600401610c3590613f59565b6002600155600f54600090849061184085610b4c565b61184a9190613f46565b6118549190613e24565b90508034146118755760405162461bcd60e51b8152600401610c3590613f90565b600254336000908152600860205260409020546201000090910461ffff169061189f908690613f46565b11156118e35760405162461bcd60e51b8152602060048201526013602482015272546f6f206d616e7920616d706c69666965727360681b6044820152606401610c35565b7f000000000000000000000000d23367155b55d67492dfdc0fc7f8bb1df7114fd96001600160a01b03166390bca2fb33866012546119219190613e24565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af115801561196c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119909190613fc7565b6119cf5760405162461bcd60e51b815260206004820152601060248201526f2737ba1030b13632903a3790313ab93760811b6044820152606401610c35565b8367ffffffffffffffff8111156119e8576119e8613e43565b604051908082528060200260200182016040528015611a11578160200160208202803683370190505b50915060005b84811015611a4d57611a28846128ba565b838281518110611a3a57611a3a613e59565b6020908102919091010152600101611a17565b506028546040516000916001600160a01b03169083908381818185875af1925050503d8060008114611a9b576040519150601f19603f3d011682016040523d82523d6000602084013e611aa0565b606091505b5050905080611ac15760405162461bcd60e51b8152600401610c3590613fe9565b50506001805592915050565b611ad561253c565b6000816001600160a01b03164760405160006040518083038185875af1925050503d8060008114611b22576040519150601f19603f3d011682016040523d82523d6000602084013e611b27565b606091505b5050905080611b485760405162461bcd60e51b8152600401610c3590613fe9565b5050565b611b5461253c565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d8116600483015260001960248301527f000000000000000000000000d23367155b55d67492dfdc0fc7f8bb1df7114fd9169063095ea7b3906044016020604051808303816000875af1158015611be4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c089190613fc7565b50565b611c1361253c565b611c1d6000613542565b565b600260015403611c415760405162461bcd60e51b8152600401610c3590613f59565b6002600155611c51838383613120565b50506001805550565b600260015403611c7c5760405162461bcd60e51b8152600401610c3590613f59565b60026001556000828152600760205260409020805461010090046001600160a01b03163314611cbd5760405162461bcd60e51b8152600401610c35906140c5565b6000815460ff166003811115611cd557611cd5613cf7565b14611d125760405162461bcd60e51b815260206004820152600d60248201526c105b1c9958591e48199d5cd959609a1b6044820152606401610c35565b600181015442600160301b90910465ffffffffffff1611611d455760405162461bcd60e51b8152600401610c35906140f0565b6011543414611d665760405162461bcd60e51b8152600401610c3590613f90565b6000600d6000846003811115611d7e57611d7e613cf7565b6003811115611d8f57611d8f613cf7565b815260208101919091526040908101600020549051632967cf8360e21b8152600481018690526001600160a01b039091169063a59f3e0c906024016020604051808303816000875af1158015611de9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e0d919061411b565b82549091508390839060ff19166001836003811115611e2e57611e2e613cf7565b021790555060018201805465ffffffffffff838116600160901b0265ffffffffffff60901b194292909216600160601b0291909116600160601b600160c01b031990921691909117179055826003811115611e8b57611e8b613cf7565b604051339086907fdf940f44a19932d19b1fa0f10b9c1246a8e1c5606636c480217c1759d65468d690600090a46028546040516000916001600160a01b03169034908381818185875af1925050503d8060008114611f05576040519150601f19603f3d011682016040523d82523d6000602084013e611f0a565b606091505b5050905080611f2b5760405162461bcd60e51b8152600401610c3590613fe9565b505060018055505050565b6060611f4061253c565b8584148015611f4e57508382145b611f905760405162461bcd60e51b815260206004820152601360248201527213195b99dd1a1cc81b9bdd08185b1a59db9959606a1b6044820152606401610c35565b858067ffffffffffffffff811115611faa57611faa613e43565b604051908082528060200260200182016040528015611fd3578160200160208202803683370190505b50915060005b8181101561207557612050898983818110611ff657611ff6613e59565b905060200201602081019061200b9190613bcf565b88888481811061201d5761201d613e59565b9050602002013587878581811061203657612036613e59565b905060200201602081019061204b91906139e9565b613592565b83828151811061206257612062613e59565b6020908102919091010152600101611fd9565b50509695505050505050565b61208961253c565b601481146120ca5760405162461bcd60e51b815260206004820152600e60248201526d092dcecc2d8d2c840d8cadccee8d60931b6044820152606401610c35565b8060005b8181101561210c578383828181106120e8576120e8613e59565b905060200201356013826014811061210257612102613e59565b01556001016120ce565b50505050565b6002600154036121345760405162461bcd60e51b8152600401610c3590613f59565b6002600155600061214482610b4c565b90508034146121655760405162461bcd60e51b8152600401610c3590613f90565b61216f8383612b03565b6028546040516000916001600160a01b03169083908381818185875af1925050503d80600081146121bc576040519150601f19603f3d011682016040523d82523d6000602084013e6121c1565b606091505b50509050806121e25760405162461bcd60e51b8152600401610c3590613fe9565b5050600180555050565b60026001540361220e5760405162461bcd60e51b8152600401610c3590613f59565b6002600155600081815b818110156122555761224185858381811061223557612235613e59565b90506020020135612caa565b61224b9084613f46565b9250600101612218565b5061225f82612dd9565b60405163a9059cbb60e01b8152336004820152602481018290529092507f000000000000000000000000d23367155b55d67492dfdc0fc7f8bb1df7114fd96001600160a01b03169063a9059cbb906044016020604051808303816000875af11580156122cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122f39190613fc7565b6122fc57600080fd5b60405182815233907f69cba1622d26658c0420d7e6b9b673716deaa320ceeac6aed1860ab4a6f601529060200160405180910390a25050600180555050565b6013816014811061234b57600080fd5b0154905081565b61235a61253c565b6001600160a01b0381166123bf5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c35565b611c0881613542565b6123d061253c565b601255565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915260008281526007602052604090819020815161010081019092528054829060ff16600381111561244857612448613cf7565b600381111561245957612459613cf7565b815281546001600160a01b03610100820416602083015261ffff600160a81b820416604083015265ffffffffffff600160b81b909104811660608301526001909201548083166080830152600160301b8104831660a0830152600160601b8104831660c0830152600160901b900490911660e09091015292915050565b6124de61253c565b80600d60008460038111156124f5576124f5613cf7565b600381111561250657612506613cf7565b815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055505050565b6000546001600160a01b03163314611c1d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c35565b600680546001810190915560408051610100810190915283516000929190819060038111156125c7576125c7613cf7565b815260200185602001516001600160a01b03168152602001856080015161ffff1681526020018560a0015165ffffffffffff168152602001856040015165ffffffffffff168152602001856060015165ffffffffffff1681526020018560c0015165ffffffffffff1681526020018560e0015165ffffffffffff168152506007600083815260200190815260200160002060008201518160000160006101000a81548160ff0219169083600381111561268257612682613cf7565b0217905550602082015181546040840151606085015165ffffffffffff908116600160b81b0265ffffffffffff60b81b1961ffff909316600160a81b0261ffff60a81b196001600160a01b039096166101000295909516610100600160b81b031990941693909317939093171617825560808301516001909201805460a085015160c086015160e0909601518416600160901b0265ffffffffffff60901b19968516600160601b0296909616600160601b600160c01b0319918516600160301b026001600160601b0319909316959094169490941717929092161791909117905560008451600381111561277857612778613cf7565b1461283257600d60008560000151600381111561279757612797613cf7565b60038111156127a8576127a8613cf7565b81526020810191909152604090810160009081205460e08701519251638c84c68360e01b81526004810185905265ffffffffffff909316602484015260448301919091526001600160a01b031690638c84c68390606401600060405180830381600087803b15801561281957600080fd5b505af115801561282d573d6000803e3d6000fd5b505050505b602080850180516001600160a01b039081166000908152600884526040808220805460018101909155845184168352600986528183208184528652818320879055868352600a909552808220859055925192519290911691849187917f12032246d9527ba32d0b656f176935871584cd8136c6c205e14e63ed379d9bb09190a4509392505050565b600080821180156128d1575060025461ffff168211155b6129125760405162461bcd60e51b81526020600482015260126024820152714d75737420626520312d36206d6f6e74687360701b6044820152606401610c35565b6006805460018101909155604080516101008101909152806000815233602082015260006040820181905260608201524265ffffffffffff16608082015260a0016129608562278d00613e24565b61296a9042613f46565b65ffffffffffff168152600060208083018290526040928301829052848252600790522081518154829060ff191660018360038111156129ac576129ac613cf7565b021790555060208281015182546040808601516060870151610100600160b81b03199093166101006001600160a01b039095169490940261ffff60a81b191693909317600160a81b61ffff909416939093029290921765ffffffffffff60b81b1916600160b81b65ffffffffffff9283160217845560808501516001948501805460a088015160c089015160e0909901519385166001600160601b031990921691909117600160301b9185169190910217600160601b600160c01b031916600160601b9784169790970265ffffffffffff60901b191696909617600160901b9190921602179093553360008181526008835284812080549485019055600983528481208482528352848120869055858152600a8352849020839055925186815291929184917f915b4bd5e5ec615d95d8794152a9d65ecb9d2244a84a094ffcbaca376f2a02fa910160405180910390a35092915050565b6000828152600760205260409020805461010090046001600160a01b03163314612b3f5760405162461bcd60e51b8152600401610c35906140c5565b60035460018201544291612b6191600160301b900465ffffffffffff16613f46565b1015612ba65760405162461bcd60e51b815260206004820152601460248201527311dc9858d9481c195c9a5bd908195e1c1a5c995960621b6044820152606401610c35565b612bb38262278d00613e24565b600182018054600690612bd6908490600160301b900465ffffffffffff16614143565b825465ffffffffffff9182166101009390930a928302919092021990911617905550600254612c0c9061ffff1662278d00614162565b612c1b9062ffffff1642613f46565b6001820154600160301b900465ffffffffffff1610612c6e5760405162461bcd60e51b815260206004820152600f60248201526e546f6f206d616e79206d6f6e74687360881b6044820152606401610c35565b604051828152339084907f5f2594387e270c9989f6a37982023109dbc9b27463e4ac9fd67d340b2fa207dd9060200160405180910390a3505050565b6000818152600760205260408120805461010090046001600160a01b03163314612ce65760405162461bcd60e51b8152600401610c35906140c5565b6000815460ff166003811115612cfe57612cfe613cf7565b14612d3d5760405162461bcd60e51b815260206004820152600f60248201526e135d5cdd081899481d5b999d5cd959608a1b6044820152606401610c35565b600181015442600160301b90910465ffffffffffff1611612d705760405162461bcd60e51b8152600401610c35906140f0565b612d798361158f565b8154909250600160a81b900461ffff16816015612d958361418d565b82546101009290920a61ffff81810219909316919092169190910217905550805465ffffffffffff60b81b1916600160b81b4265ffffffffffff1602179055919050565b602a54600090819061271090612df39061ffff1685613e24565b612dfd91906141c4565b60408051600280825260608201835292935060009290916020830190803683370190505090507f000000000000000000000000d23367155b55d67492dfdc0fc7f8bb1df7114fd981600081518110612e5757612e57613e59565b60200260200101906001600160a01b031690816001600160a01b0316815250507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881600181518110612eab57612eab613e59565b6001600160a01b039283166020918202929092010152604051635c11d79560e01b81527f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d90911690635c11d79590612f109085906000908690309042906004016141e6565b600060405180830381600087803b158015612f2a57600080fd5b505af1158015612f3e573d6000803e3d6000fd5b50506040516370a0823160e01b815230600482015260009250600291506001600160a01b037f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4816906370a0823190602401602060405180830381865afa158015612fac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd09190614015565b612fda91906141c4565b60275460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529192507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48169063a9059cbb906044016020604051808303816000875af115801561304f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130739190613fc7565b5060295460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390527f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489091169063a9059cbb906044016020604051808303816000875af11580156130e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061310c9190613fc7565b5061311783866140b2565b95945050505050565b600083815260076020526040812090815460ff16600381111561314557613145613cf7565b036131825760405162461bcd60e51b815260206004820152600d60248201526c135d5cdd08189948199d5cd959609a1b6044820152606401610c35565b60055460018201546131a390600160601b900465ffffffffffff16426140b2565b116131e75760405162461bcd60e51b815260206004820152601460248201527310d85b9b9bdd0818db185a5b48115512081e595d60621b6044820152606401610c35565b811561332a57600181015442600160301b90910465ffffffffffff16116132205760405162461bcd60e51b8152600401610c35906140f0565b8054600090600d90829060ff16600381111561323e5761323e613cf7565b600381111561324f5761324f613cf7565b8152602081019190915260409081016000205490516358db332960e11b81526001600160a01b039091169063b1b666529061329290889088908890600401614257565b6020604051808303816000875af11580156132b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132d59190614015565b825460405191925033916101009091046001600160a01b03169087907fa924a34e4fc8eaee5b8cfa925b99aaf25c8e7604b64548958dce31a5e23b695b906133209086815260200190565b60405180910390a4505b600181015442600160901b90910465ffffffffffff161161210c57600181015442600160301b90910465ffffffffffff1611156134535780546001600160a01b037f000000000000000000000000d23367155b55d67492dfdc0fc7f8bb1df7114fd981169163a9059cbb9161010082041690600e9060009060ff1660038111156133b6576133b6613cf7565b60038111156133c7576133c7613cf7565b8152602001908152602001600020546040518363ffffffff1660e01b81526004016134079291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015613426573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061344a9190613fc7565b61345357600080fd5b8054600d9060009060ff16600381111561346f5761346f613cf7565b600381111561348057613480613cf7565b815260208101919091526040908101600020549051637f8661a160e01b8152600481018690526001600160a01b0390911690637f8661a190602401600060405180830381600087803b1580156134d557600080fd5b505af11580156134e9573d6000803e3d6000fd5b5050825460ff1916835550506001018054600160601b600160c01b0319169055505050565b600080826000036135245750600090508061353b565b6001838581613535576135356141ae565b04915091505b9250929050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60025460009061ffff168311156135dd5760405162461bcd60e51b815260206004820152600f60248201526e546f6f206d616e79206d6f6e74687360881b6044820152606401610c35565b6006805460018082019092556001600160a01b038616600090815260086020526040812080549384019055909190808086600381111561361f5761361f613cf7565b146136cf57429150600d600087600381111561363d5761363d613cf7565b600381111561364e5761364e613cf7565b815260208101919091526040908101600020549051632967cf8360e21b8152600481018690526001600160a01b039091169063a59f3e0c906024016020604051808303816000875af11580156136a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136cc919061411b565b90505b6040518061010001604052808760038111156136ed576136ed613cf7565b81526001600160a01b038a16602082015260006040820181905260608201524265ffffffffffff16608082015260a00161372a8962278d00613e24565b6137349042613f46565b65ffffffffffff9081168252848116602080840191909152908416604092830152600087815260079091522081518154829060ff1916600183600381111561377e5761377e613cf7565b021790555060208281015182546040808601516060870151610100600160b81b03199093166101006001600160a01b039586160261ffff60a81b191617600160a81b61ffff909216919091021765ffffffffffff60b81b1916600160b81b65ffffffffffff9384160217855560808601516001909501805460a088015160c089015160e0909901519785166001600160601b031990921691909117600160301b9185169190910217600160601b600160c01b031916600160601b9784169790970265ffffffffffff60901b191696909617600160901b95909216949094021790935599909116600090815260098a528181208582528a52818120869055858152600a9099529097209190915550949350505050565b803561ffff811681146138a557600080fd5b919050565b6000602082840312156138bc57600080fd5b6138c582613893565b9392505050565b60048110611c0857600080fd5b600080604083850312156138ec57600080fd5b82356138f7816138cc565b946020939093013593505050565b60006020828403121561391757600080fd5b5035919050565b60008083601f84011261393057600080fd5b50813567ffffffffffffffff81111561394857600080fd5b6020830191508360208260051b850101111561353b57600080fd5b6000806020838503121561397657600080fd5b823567ffffffffffffffff81111561398d57600080fd5b6139998582860161391e565b90969095509350505050565b6020808252825182820181905260009190848201906040850190845b818110156139dd578351835292840192918401916001016139c1565b50909695505050505050565b6000602082840312156139fb57600080fd5b81356138c5816138cc565b600080600060408486031215613a1b57600080fd5b833567ffffffffffffffff811115613a3257600080fd5b613a3e8682870161391e565b909790965060209590950135949350505050565b6001600160a01b0381168114611c0857600080fd5b60008060408385031215613a7a57600080fd5b82356138f781613a52565b60008060408385031215613a9857600080fd5b8235613aa381613a52565b91506020830135613ab381613a52565b809150509250929050565b60008060008060808587031215613ad457600080fd5b843593506020850135925060408501359150613af260608601613893565b905092959194509250565b600080600060608486031215613b1257600080fd5b505081359360208301359350604090920135919050565b60008060008060408587031215613b3f57600080fd5b843567ffffffffffffffff80821115613b5757600080fd5b613b638883890161391e565b90965094506020870135915080821115613b7c57600080fd5b50613b898782880161391e565b95989497509550505050565b600060608284031215613ba757600080fd5b50919050565b60008060408385031215613bc057600080fd5b50508035926020909101359150565b600060208284031215613be157600080fd5b81356138c581613a52565b600080600060408486031215613c0157600080fd5b83359250602084013567ffffffffffffffff811115613c1f57600080fd5b613c2b8682870161391e565b9497909650939450505050565b60008060408385031215613c4b57600080fd5b823591506020830135613ab3816138cc565b60008060008060008060608789031215613c7657600080fd5b863567ffffffffffffffff80821115613c8e57600080fd5b613c9a8a838b0161391e565b90985096506020890135915080821115613cb357600080fd5b613cbf8a838b0161391e565b90965094506040890135915080821115613cd857600080fd5b50613ce589828a0161391e565b979a9699509497509295939492505050565b634e487b7160e01b600052602160045260246000fd5b815161010082019060048110613d3357634e487b7160e01b600052602160045260246000fd5b808352506020830151613d5160208401826001600160a01b03169052565b506040830151613d67604084018261ffff169052565b506060830151613d81606084018265ffffffffffff169052565b506080830151613d9b608084018265ffffffffffff169052565b5060a0830151613db560a084018265ffffffffffff169052565b5060c0830151613dcf60c084018265ffffffffffff169052565b5060e0830151613de960e084018265ffffffffffff169052565b5092915050565b60008060408385031215613e0357600080fd5b8235613aa3816138cc565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615613e3e57613e3e613e0e565b500290565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b604051610120810167ffffffffffffffff81118282101715613ea157634e487b7160e01b600052604160045260246000fd5b60405290565b80516138a5816138cc565b80516138a581613a52565b60006101208284031215613ed057600080fd5b613ed8613e6f565b613ee183613ea7565b8152613eef60208401613eb2565b602082015260408301516040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152508091505092915050565b80820180821115610b5c57610b5c613e0e565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252601c908201527f496e76616c69642045746865722076616c75652070726f766964656400000000604082015260600190565b600060208284031215613fd957600080fd5b815180151581146138c557600080fd5b602080825260129082015271086deead8c840dcdee840e6cadcc8408aa8960731b604082015260600190565b60006020828403121561402757600080fd5b5051919050565b60008161403d5761403d613e0e565b506000190190565b80546001600160a01b0319166001600160a01b0392909216919091179055565b813561407081613a52565b61407a8183614045565b50602082013561408981613a52565b6140968160018401614045565b5060408201356140a581613a52565b61126a8160028401614045565b81810381811115610b5c57610b5c613e0e565b6020808252601190820152700496e76616c6964206f776e65727368697607c1b604082015260600190565b602080825260119082015270105b5c1b1a599a595c88195e1c1a5c9959607a1b604082015260600190565b60006020828403121561412d57600080fd5b815165ffffffffffff811681146138c557600080fd5b65ffffffffffff818116838216019080821115613de957613de9613e0e565b600062ffffff8083168185168183048111821515161561418457614184613e0e565b02949350505050565b600061ffff8083168181036141a4576141a4613e0e565b6001019392505050565b634e487b7160e01b600052601260045260246000fd5b6000826141e157634e487b7160e01b600052601260045260246000fd5b500490565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b818110156142365784516001600160a01b031683529383019391830191600101614211565b50506001600160a01b03969096166060850152505050608001529392505050565b838152604060208201819052810182905260006001600160fb1b0383111561427e57600080fd5b8260051b808560608501379190910160600194935050505056fea26469706673582212206a6a1cff86d1f491782e476233bc317274211f6105a240f471a02298a82e884a64736f6c63430008100033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d23367155b55d67492dfdc0fc7f8bb1df7114fd90000000000000000000000004b81d30d621e8a22ca6016ec8053e3dfaa3d5edf0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
-----Decoded View---------------
Arg [0] : _amplifi (address): 0xD23367155B55d67492DFDC0FC7f8bB1dF7114fD9
Arg [1] : _oldAmplifiNode (address): 0x4B81D30d621e8a22cA6016EC8053E3dfaA3d5edf
Arg [2] : _router (address): 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
Arg [3] : _usdc (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000d23367155b55d67492dfdc0fc7f8bb1df7114fd9
Arg [1] : 0000000000000000000000004b81d30d621e8a22ca6016ec8053e3dfaa3d5edf
Arg [2] : 0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d
Arg [3] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.