Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
EtherFiNode
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 20000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import "./interfaces/IEtherFiNode.sol"; import "./interfaces/IEtherFiNodesManager.sol"; import "./interfaces/IProtocolRevenueManager.sol"; import "@openzeppelin/contracts/utils/math/Math.sol"; import "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; contract EtherFiNode is IEtherFiNode { address public etherFiNodesManager; // TODO: reduce the size of these varaibles uint256 public localRevenueIndex; uint256 public vestedAuctionRewards; string public ipfsHashForEncryptedValidatorKey; uint32 public exitRequestTimestamp; uint32 public exitTimestamp; uint32 public stakingStartTimestamp; VALIDATOR_PHASE public phase; //-------------------------------------------------------------------------------------- //---------------------------------- CONSTRUCTOR ------------------------------------ //-------------------------------------------------------------------------------------- /// @custom:oz-upgrades-unsafe-allow constructor constructor() { stakingStartTimestamp = type(uint32).max; } function initialize(address _etherFiNodesManager) public { require(stakingStartTimestamp == 0, "already initialised"); require(_etherFiNodesManager != address(0), "No zero addresses"); stakingStartTimestamp = uint32(block.timestamp); etherFiNodesManager = _etherFiNodesManager; } //-------------------------------------------------------------------------------------- //---------------------------- STATE-CHANGING FUNCTIONS ------------------------------ //-------------------------------------------------------------------------------------- /// @notice Based on the sources where they come from, the staking rewards are split into /// - those from the execution layer: transaction fees and MEV /// - those from the consensus layer: Pstaking rewards for attesting the state of the chain, /// proposing a new block, or being selected in a validator sync committe /// To receive the rewards from the execution layer, it should have 'receive()' function. receive() external payable {} /// @notice Set the validator phase /// @param _phase the new phase function setPhase( VALIDATOR_PHASE _phase ) external onlyEtherFiNodeManagerContract { phase = _phase; } /// @notice Set the deposit data /// @param _ipfsHash the deposit data function setIpfsHashForEncryptedValidatorKey( string calldata _ipfsHash ) external onlyEtherFiNodeManagerContract { ipfsHashForEncryptedValidatorKey = _ipfsHash; } function setLocalRevenueIndex( uint256 _localRevenueIndex ) external payable onlyEtherFiNodeManagerContract { localRevenueIndex = _localRevenueIndex; } function setExitRequestTimestamp() external onlyEtherFiNodeManagerContract { require(exitRequestTimestamp == 0, "Exit request was already sent."); exitRequestTimestamp = uint32(block.timestamp); } function markExited( uint32 _exitTimestamp ) external onlyEtherFiNodeManagerContract { require(_exitTimestamp <= block.timestamp, "Invalid exit timesamp"); phase = VALIDATOR_PHASE.EXITED; exitTimestamp = _exitTimestamp; } function markBeingSlahsed() external onlyEtherFiNodeManagerContract { phase = VALIDATOR_PHASE.BEING_SLASHED; } function receiveVestedRewardsForStakers() external payable onlyProtocolRevenueManagerContract { require( vestedAuctionRewards == 0, "already received the vested auction fee reward" ); vestedAuctionRewards = msg.value; } function processVestedAuctionFeeWithdrawal() external onlyEtherFiNodeManagerContract { if (_getClaimableVestedRewards() > 0) { vestedAuctionRewards = 0; } } function moveRewardsToManager( uint256 _amount ) external onlyEtherFiNodeManagerContract { (bool sent, ) = payable(etherFiNodesManager).call{value: _amount}(""); require(sent, "Failed to send Ether"); } function withdrawFunds( address _treasury, uint256 _treasuryAmount, address _operator, uint256 _operatorAmount, address _tnftHolder, uint256 _tnftAmount, address _bnftHolder, uint256 _bnftAmount ) external onlyEtherFiNodeManagerContract { // the recipients of the funds must be able to receive the fund // For example, if it is a smart contract, // they should implement either recieve() or fallback() properly // It's designed to prevent malicious actors from pausing the withdrawals bool sent; (sent, ) = payable(_operator).call{value: _operatorAmount}(""); _treasuryAmount += (!sent) ? _operatorAmount : 0; (sent, ) = payable(_tnftHolder).call{value: _tnftAmount}(""); _treasuryAmount += (!sent) ? _tnftAmount : 0; (sent, ) = payable(_bnftHolder).call{value: _bnftAmount}(""); _treasuryAmount += (!sent) ? _bnftAmount : 0; (sent, ) = _treasury.call{value: _treasuryAmount}(""); require(sent, "Failed to send Ether"); } /// @notice compute the payouts for {staking, protocol} rewards and vested auction fee to the individuals /// @param _stakingRewards a flag to be set if the caller wants to compute the payouts for the stkaing rewards /// @param _protocolRewards a flag to be set if the caller wants to compute the payouts for the protocol rewards /// @param _vestedAuctionFee a flag to be set if the caller wants to compute the payouts for the vested auction fee /// @param _SRsplits the splits for the Staking Rewards /// @param _SRscale the scale /// @param _PRsplits the splits for the Protocol Rewards /// @param _PRscale the scale /// /// @return toNodeOperator the payout to the Node Operator /// @return toTnft the payout to the T-NFT holder /// @return toBnft the payout to the B-NFT holder /// @return toTreasury the payout to the Treasury function getRewardsPayouts( bool _stakingRewards, bool _protocolRewards, bool _vestedAuctionFee, IEtherFiNodesManager.RewardsSplit memory _SRsplits, uint256 _SRscale, IEtherFiNodesManager.RewardsSplit memory _PRsplits, uint256 _PRscale ) public view onlyEtherFiNodeManagerContract returns (uint256, uint256, uint256, uint256) { uint256 operator; uint256 tnft; uint256 bnft; uint256 treasury; uint256[] memory tmps = new uint256[](4); if (_stakingRewards) { (tmps[0], tmps[1], tmps[2], tmps[3]) = getStakingRewardsPayouts( _SRsplits, _SRscale ); operator += tmps[0]; tnft += tmps[1]; bnft += tmps[2]; treasury += tmps[3]; } if (_protocolRewards) { (tmps[0], tmps[1], tmps[2], tmps[3]) = getProtocolRewardsPayouts( _PRsplits, _PRscale ); operator += tmps[0]; tnft += tmps[1]; bnft += tmps[2]; treasury += tmps[3]; } if (_vestedAuctionFee) { uint256 rewards = _getClaimableVestedRewards(); uint256 toTnft = (rewards * 29) / 32; tnft += toTnft; // 29 / 32 bnft += rewards - toTnft; // 3 / 32 } return (operator, tnft, bnft, treasury); } /// @notice get the accrued staking rewards payouts to (toNodeOperator, toTnft, toBnft, toTreasury) /// @param _splits the splits for the staking rewards /// @param _scale the scale = SUM(_splits) /// /// @return toNodeOperator the payout to the Node Operator /// @return toTnft the payout to the T-NFT holder /// @return toBnft the payout to the B-NFT holder /// @return toTreasury the payout to the Treasury function getStakingRewardsPayouts( IEtherFiNodesManager.RewardsSplit memory _splits, uint256 _scale ) public view onlyEtherFiNodeManagerContract returns ( uint256 toNodeOperator, uint256 toTnft, uint256 toBnft, uint256 toTreasury ) { uint256 balance = address(this).balance; uint256 rewards = (balance > vestedAuctionRewards) ? balance - vestedAuctionRewards : 0; if (rewards >= 32 ether) { rewards -= 32 ether; } else if (rewards >= 8 ether) { // In a case of Slashing, without the Oracle, the exact staking rewards cannot be computed in this case // Assume no staking rewards in this case. return (0, 0, 0, 0); } ( uint256 operator, uint256 tnft, uint256 bnft, uint256 treasury ) = calculatePayouts(rewards, _splits, _scale); if (exitRequestTimestamp > 0) { uint256 daysPassedSinceExitRequest = _getDaysPassedSince( exitRequestTimestamp, uint32(block.timestamp) ); if (daysPassedSinceExitRequest >= 14) { treasury += operator; operator = 0; } } return (operator, tnft, bnft, treasury); } /// @notice get the accrued protocol rewards payouts to (toNodeOperator, toTnft, toBnft, toTreasury) /// @param _splits the splits for the protocol rewards /// @param _scale the scale = SUM(_splits) /// /// @return toNodeOperator the payout to the Node Operator /// @return toTnft the payout to the T-NFT holder /// @return toBnft the payout to the B-NFT holder /// @return toTreasury the payout to the Treasury function getProtocolRewardsPayouts( IEtherFiNodesManager.RewardsSplit memory _splits, uint256 _scale ) public view onlyEtherFiNodeManagerContract returns ( uint256 toNodeOperator, uint256 toTnft, uint256 toBnft, uint256 toTreasury ) { if (localRevenueIndex == 0) { return (0, 0, 0, 0); } uint256 globalRevenueIndex = IProtocolRevenueManager( protocolRevenueManagerAddress() ).globalRevenueIndex(); uint256 rewards = globalRevenueIndex - localRevenueIndex; return calculatePayouts(rewards, _splits, _scale); } /// @notice compute the non exit penalty for the b-nft holder /// @param _principal the principal for the non exit penalty (e.g., 1 ether) /// @param _dailyPenalty the dailty penalty for the non exit penalty /// @param _exitTimestamp the exit timestamp for the validator node function getNonExitPenalty( uint128 _principal, uint64 _dailyPenalty, uint32 _exitTimestamp ) public view onlyEtherFiNodeManagerContract returns (uint256) { if (exitRequestTimestamp == 0) { return 0; } uint256 daysElapsed = _getDaysPassedSince( exitRequestTimestamp, _exitTimestamp ); // full penalty if (daysElapsed > 365) { return _principal; } uint256 remaining = _principal; while (daysElapsed > 0) { uint256 exponent = Math.min(7, daysElapsed); // TODO: Re-calculate bounds remaining = (remaining * (100 - uint256(_dailyPenalty)) ** exponent) / (100 ** exponent); daysElapsed -= Math.min(7, daysElapsed); } return _principal - remaining; } /// @notice Given the current balance of the ether fi node after its EXIT, /// Compute the payouts to {node operator, t-nft holder, b-nft holder, treasury} /// @param _splits the splits for the staking rewards /// @param _scale the scale = SUM(_splits) /// @param _principal the principal for the non exit penalty (e.g., 1 ether) /// @param _dailyPenalty the dailty penalty for the non exit penalty /// /// @return toNodeOperator the payout to the Node Operator /// @return toTnft the payout to the T-NFT holder /// @return toBnft the payout to the B-NFT holder /// @return toTreasury the payout to the Treasury function getFullWithdrawalPayouts( IEtherFiNodesManager.RewardsSplit memory _splits, uint256 _scale, uint128 _principal, uint64 _dailyPenalty ) external view returns ( uint256 toNodeOperator, uint256 toTnft, uint256 toBnft, uint256 toTreasury ) { uint256 balance = address(this).balance - (vestedAuctionRewards - _getClaimableVestedRewards()); require( balance >= 16 ether, "not enough balance for full withdrawal" ); require( phase == VALIDATOR_PHASE.EXITED, "validator node is not exited" ); // (toNodeOperator, toTnft, toBnft, toTreasury) uint256[] memory payouts = new uint256[](4); // Compute the payouts for the rewards = (staking rewards + vested auction fee rewards) // the protocol rewards must be paid off already in 'processNodeExit' ( payouts[0], payouts[1], payouts[2], payouts[3] ) = getRewardsPayouts( true, false, true, _splits, _scale, _splits, _scale ); balance -= (payouts[0] + payouts[1] + payouts[2] + payouts[3]); // Compute the payouts for the principals to {B, T}-NFTs uint256 toBnftPrincipal; uint256 toTnftPrincipal; if (balance > 31.5 ether) { // 31.5 ether < balance <= 32 ether toBnftPrincipal = balance - 30 ether; } else if (balance > 26 ether) { // 26 ether < balance <= 31.5 ether toBnftPrincipal = 1.5 ether; } else if (balance > 25.5 ether) { // 25.5 ether < balance <= 26 ether toBnftPrincipal = 1.5 ether - (26 ether - balance); } else { // 16 ether <= balance <= 25.5 ether toBnftPrincipal = 1 ether; } toTnftPrincipal = balance - toBnftPrincipal; payouts[1] += toTnftPrincipal; payouts[2] += toBnftPrincipal; // Deduct the NonExitPenalty from the payout to the B-NFT uint256 bnftNonExitPenalty = getNonExitPenalty( _principal, _dailyPenalty, exitTimestamp ); payouts[2] -= bnftNonExitPenalty; // While the NonExitPenalty keeps growing till 1 ether, // the incentive to the node operator stops growing at 0.5 ether // the rest goes to the treasury if (bnftNonExitPenalty > 0.5 ether) { payouts[0] += 0.5 ether; payouts[3] += bnftNonExitPenalty - 0.5 ether; } else { payouts[0] += bnftNonExitPenalty; } require( payouts[0] + payouts[1] + payouts[2] + payouts[3] == address(this).balance - (vestedAuctionRewards - _getClaimableVestedRewards()), "Incorrect Amount" ); return (payouts[0], payouts[1], payouts[2], payouts[3]); } function _getClaimableVestedRewards() internal view returns (uint256) { if (vestedAuctionRewards == 0) { return 0; } uint256 vestingPeriodInDays = IProtocolRevenueManager( protocolRevenueManagerAddress() ).auctionFeeVestingPeriodForStakersInDays(); uint256 daysPassed = _getDaysPassedSince( stakingStartTimestamp, uint32(block.timestamp) ); if (daysPassed >= vestingPeriodInDays) { return vestedAuctionRewards; } else { return 0; } } function _getDaysPassedSince( uint32 _startTimestamp, uint32 _endTimestamp ) internal pure returns (uint256) { if (_endTimestamp <= _startTimestamp) { return 0; } uint256 timeElapsed = _endTimestamp - _startTimestamp; return uint256(timeElapsed / (24 * 3_600)); } function calculatePayouts( uint256 _totalAmount, IEtherFiNodesManager.RewardsSplit memory _splits, uint256 _scale ) public pure returns (uint256, uint256, uint256, uint256) { require( _splits.nodeOperator + _splits.tnft + _splits.bnft + _splits.treasury == _scale, "Incorrect Splits" ); uint256 operator = (_totalAmount * _splits.nodeOperator) / _scale; uint256 tnft = (_totalAmount * _splits.tnft) / _scale; uint256 bnft = (_totalAmount * _splits.bnft) / _scale; uint256 treasury = _totalAmount - (bnft + tnft + operator); return (operator, tnft, bnft, treasury); } function protocolRevenueManagerAddress() internal view returns (address) { return IEtherFiNodesManager(etherFiNodesManager) .protocolRevenueManagerContract(); } function implementation() external view returns (address) { bytes32 slot = bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1); address implementation; assembly { implementation := sload(slot) } IBeacon beacon = IBeacon(implementation); return beacon.implementation(); } //-------------------------------------------------------------------------------------- //----------------------------------- MODIFIERS -------------------------------------- //-------------------------------------------------------------------------------------- modifier onlyEtherFiNodeManagerContract() { require( msg.sender == etherFiNodesManager, "Only EtherFiNodeManager Contract" ); _; } modifier onlyProtocolRevenueManagerContract() { require( msg.sender == protocolRevenueManagerAddress(), "Only protocol revenue manager contract function" ); _; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import "./IEtherFiNodesManager.sol"; interface IEtherFiNode { //The state of the validator enum VALIDATOR_PHASE { NOT_INITIALIZED, STAKE_DEPOSITED, LIVE, EXITED, CANCELLED, BEING_SLASHED } // VIEW functions function phase() external view returns (VALIDATOR_PHASE); function ipfsHashForEncryptedValidatorKey() external view returns (string memory); function localRevenueIndex() external view returns (uint256); function stakingStartTimestamp() external view returns (uint32); function exitRequestTimestamp() external view returns (uint32); function exitTimestamp() external view returns (uint32); function vestedAuctionRewards() external view returns (uint256); function getNonExitPenalty( uint128 _principal, uint64 _dailyPenalty, uint32 _endTimestamp ) external view returns (uint256); function calculatePayouts( uint256 _totalAmount, IEtherFiNodesManager.RewardsSplit memory _splits, uint256 _scale ) external view returns (uint256, uint256, uint256, uint256); function getStakingRewardsPayouts( IEtherFiNodesManager.RewardsSplit memory _splits, uint256 _scale ) external view returns (uint256, uint256, uint256, uint256); function getProtocolRewardsPayouts( IEtherFiNodesManager.RewardsSplit memory _splits, uint256 _scale ) external view returns (uint256, uint256, uint256, uint256); function getRewardsPayouts( bool _stakingRewards, bool _protocolRewards, bool _vestedAuctionFee, IEtherFiNodesManager.RewardsSplit memory _SRsplits, uint256 _SRscale, IEtherFiNodesManager.RewardsSplit memory _PRsplits, uint256 _PRscale ) external view returns (uint256, uint256, uint256, uint256); function getFullWithdrawalPayouts( IEtherFiNodesManager.RewardsSplit memory _splits, uint256 _scale, uint128 _principal, uint64 _dailyPenalty ) external view returns (uint256, uint256, uint256, uint256); // Non-VIEW functions function setPhase(VALIDATOR_PHASE _phase) external; function setIpfsHashForEncryptedValidatorKey( string calldata _ipfs ) external; function setLocalRevenueIndex(uint256 _localRevenueIndex) external payable; function setExitRequestTimestamp() external; function markExited(uint32 _exitTimestamp) external; function markBeingSlahsed() external; function receiveVestedRewardsForStakers() external payable; function processVestedAuctionFeeWithdrawal() external; // Withdraw Rewards function moveRewardsToManager(uint256 _amount) external; function withdrawFunds( address _treasury, uint256 _treasuryAmount, address _operator, uint256 _operatorAmount, address _tnftHolder, uint256 _tnftAmount, address _bnftHolder, uint256 _bnftAmount ) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import "./IEtherFiNode.sol"; interface IEtherFiNodesManager { enum ValidatorRecipientType { TNFTHOLDER, BNFTHOLDER, TREASURY, OPERATOR } struct RewardsSplit { uint64 treasury; uint64 nodeOperator; uint64 tnft; uint64 bnft; } // VIEW functions function numberOfValidators() external view returns (uint64); function etherfiNodeAddress( uint256 _validatorId ) external view returns (address); function phase( uint256 _validatorId ) external view returns (IEtherFiNode.VALIDATOR_PHASE phase); function ipfsHashForEncryptedValidatorKey( uint256 _validatorId ) external view returns (string memory); function localRevenueIndex(uint256 _validatorId) external returns (uint256); function vestedAuctionRewards( uint256 _validatorId ) external returns (uint256); function generateWithdrawalCredentials( address _address ) external view returns (bytes memory); function getWithdrawalCredentials( uint256 _validatorId ) external view returns (bytes memory); function isExitRequested(uint256 _validatorId) external view returns (bool); function isExited(uint256 _validatorId) external view returns (bool); function getNonExitPenalty( uint256 _validatorId, uint32 _endTimestamp ) external view returns (uint256); function getStakingRewardsPayouts( uint256 _validatorId ) external view returns (uint256, uint256, uint256, uint256); function getRewardsPayouts( uint256 _validatorId, bool _stakingRewards, bool _protocolRewards, bool _vestedAuctionFee ) external view returns (uint256, uint256, uint256, uint256); function getFullWithdrawalPayouts( uint256 _validatorId ) external view returns (uint256, uint256, uint256, uint256); function protocolRevenueManagerContract() external view returns (address); // Non-VIEW functions function initialize( address _treasuryContract, address _auctionContract, address _stakingManagerContract, address _tnftContract, address _bnftContract, address _protocolRevenueManagerContract ) external; function incrementNumberOfValidators(uint64 _count) external; function registerEtherFiNode( uint256 _validatorId, address _address ) external; function unregisterEtherFiNode(uint256 _validatorId) external; function setStakingRewardsSplit( uint64 _treasury, uint64 _nodeOperator, uint64 _tnft, uint64 _bnft ) external; function setProtocolRewardsSplit( uint64 _treasury, uint64 _nodeOperator, uint64 _tnft, uint64 _bnft ) external; function setNonExitPenaltyPrincipal( uint64 _nonExitPenaltyPrincipal ) external; function setNonExitPenaltyDailyRate( uint64 _nonExitPenaltyDailyRate ) external; function setEtherFiNodePhase( uint256 _validatorId, IEtherFiNode.VALIDATOR_PHASE _phase ) external; function setEtherFiNodeIpfsHashForEncryptedValidatorKey( uint256 _validatorId, string calldata _ipfs ) external; function setEtherFiNodeLocalRevenueIndex( uint256 _validatorId, uint256 _localRevenueIndex ) external payable; function sendExitRequest(uint256 _validatorId) external; function batchSendExitRequest(uint256[] calldata _validatorIds) external; function processNodeExit( uint256[] calldata _validatorIds, uint32[] calldata _exitTimestamp ) external; function partialWithdraw( uint256 _validatorId, bool _stakingRewards, bool _protocolRewards, bool _vestedAuctionFee ) external; function partialWithdrawBatch( uint256[] calldata _validatorIds, bool _stakingRewards, bool _protocolRewards, bool _vestedAuctionFee ) external; function partialWithdrawBatchGroupByOperator( address _operator, uint256[] memory _validatorIds, bool _stakingRewards, bool _protocolRewards, bool _vestedAuctionFee ) external; function fullWithdraw(uint256 _validatorId) external; function fullWithdrawBatch(uint256[] calldata _validatorIds) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IProtocolRevenueManager { struct AuctionRevenueSplit { uint64 treasurySplit; uint64 nodeOperatorSplit; uint64 tnftHolderSplit; uint64 bnftHolderSplit; } function globalRevenueIndex() external view returns (uint256); function auctionFeeVestingPeriodForStakersInDays() external view returns (uint128); function getAccruedAuctionRevenueRewards( uint256 _validatorId ) external view returns (uint256); function addAuctionRevenue(uint256 _validatorId) external payable; function distributeAuctionRevenue( uint256 _validatorId ) external returns (uint256); function setEtherFiNodesManagerAddress( address _etherFiNodesManager ) external; function setAuctionManagerAddress(address _auctionManager) external; function setAuctionRewardVestingPeriod(uint128 _periodInDays) external; function setAuctionRewardSplitForStakers(uint128 _split) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.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. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
{ "remappings": [ "@openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "@openzeppelin/=lib/openzeppelin-contracts/", "@uniswap/=lib/", "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "murky/=lib/murky/src/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "safe-contracts/=lib/safe-tools/lib/safe-contracts/contracts/", "safe-tools/=lib/safe-tools/src/", "solady/=lib/safe-tools/lib/solady/src/", "solmate/=lib/safe-tools/lib/solady/lib/solmate/src/", "v3-core/=lib/v3-core/", "v3-periphery/=lib/v3-periphery/contracts/" ], "optimizer": { "enabled": true, "runs": 20000 }, "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":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"_totalAmount","type":"uint256"},{"components":[{"internalType":"uint64","name":"treasury","type":"uint64"},{"internalType":"uint64","name":"nodeOperator","type":"uint64"},{"internalType":"uint64","name":"tnft","type":"uint64"},{"internalType":"uint64","name":"bnft","type":"uint64"}],"internalType":"struct IEtherFiNodesManager.RewardsSplit","name":"_splits","type":"tuple"},{"internalType":"uint256","name":"_scale","type":"uint256"}],"name":"calculatePayouts","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"etherFiNodesManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exitRequestTimestamp","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exitTimestamp","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"treasury","type":"uint64"},{"internalType":"uint64","name":"nodeOperator","type":"uint64"},{"internalType":"uint64","name":"tnft","type":"uint64"},{"internalType":"uint64","name":"bnft","type":"uint64"}],"internalType":"struct IEtherFiNodesManager.RewardsSplit","name":"_splits","type":"tuple"},{"internalType":"uint256","name":"_scale","type":"uint256"},{"internalType":"uint128","name":"_principal","type":"uint128"},{"internalType":"uint64","name":"_dailyPenalty","type":"uint64"}],"name":"getFullWithdrawalPayouts","outputs":[{"internalType":"uint256","name":"toNodeOperator","type":"uint256"},{"internalType":"uint256","name":"toTnft","type":"uint256"},{"internalType":"uint256","name":"toBnft","type":"uint256"},{"internalType":"uint256","name":"toTreasury","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"_principal","type":"uint128"},{"internalType":"uint64","name":"_dailyPenalty","type":"uint64"},{"internalType":"uint32","name":"_exitTimestamp","type":"uint32"}],"name":"getNonExitPenalty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"treasury","type":"uint64"},{"internalType":"uint64","name":"nodeOperator","type":"uint64"},{"internalType":"uint64","name":"tnft","type":"uint64"},{"internalType":"uint64","name":"bnft","type":"uint64"}],"internalType":"struct IEtherFiNodesManager.RewardsSplit","name":"_splits","type":"tuple"},{"internalType":"uint256","name":"_scale","type":"uint256"}],"name":"getProtocolRewardsPayouts","outputs":[{"internalType":"uint256","name":"toNodeOperator","type":"uint256"},{"internalType":"uint256","name":"toTnft","type":"uint256"},{"internalType":"uint256","name":"toBnft","type":"uint256"},{"internalType":"uint256","name":"toTreasury","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_stakingRewards","type":"bool"},{"internalType":"bool","name":"_protocolRewards","type":"bool"},{"internalType":"bool","name":"_vestedAuctionFee","type":"bool"},{"components":[{"internalType":"uint64","name":"treasury","type":"uint64"},{"internalType":"uint64","name":"nodeOperator","type":"uint64"},{"internalType":"uint64","name":"tnft","type":"uint64"},{"internalType":"uint64","name":"bnft","type":"uint64"}],"internalType":"struct IEtherFiNodesManager.RewardsSplit","name":"_SRsplits","type":"tuple"},{"internalType":"uint256","name":"_SRscale","type":"uint256"},{"components":[{"internalType":"uint64","name":"treasury","type":"uint64"},{"internalType":"uint64","name":"nodeOperator","type":"uint64"},{"internalType":"uint64","name":"tnft","type":"uint64"},{"internalType":"uint64","name":"bnft","type":"uint64"}],"internalType":"struct IEtherFiNodesManager.RewardsSplit","name":"_PRsplits","type":"tuple"},{"internalType":"uint256","name":"_PRscale","type":"uint256"}],"name":"getRewardsPayouts","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"treasury","type":"uint64"},{"internalType":"uint64","name":"nodeOperator","type":"uint64"},{"internalType":"uint64","name":"tnft","type":"uint64"},{"internalType":"uint64","name":"bnft","type":"uint64"}],"internalType":"struct IEtherFiNodesManager.RewardsSplit","name":"_splits","type":"tuple"},{"internalType":"uint256","name":"_scale","type":"uint256"}],"name":"getStakingRewardsPayouts","outputs":[{"internalType":"uint256","name":"toNodeOperator","type":"uint256"},{"internalType":"uint256","name":"toTnft","type":"uint256"},{"internalType":"uint256","name":"toBnft","type":"uint256"},{"internalType":"uint256","name":"toTreasury","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_etherFiNodesManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ipfsHashForEncryptedValidatorKey","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"localRevenueIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"markBeingSlahsed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_exitTimestamp","type":"uint32"}],"name":"markExited","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"moveRewardsToManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"phase","outputs":[{"internalType":"enum IEtherFiNode.VALIDATOR_PHASE","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"processVestedAuctionFeeWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"receiveVestedRewardsForStakers","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"setExitRequestTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_ipfsHash","type":"string"}],"name":"setIpfsHashForEncryptedValidatorKey","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_localRevenueIndex","type":"uint256"}],"name":"setLocalRevenueIndex","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"enum IEtherFiNode.VALIDATOR_PHASE","name":"_phase","type":"uint8"}],"name":"setPhase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingStartTimestamp","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vestedAuctionRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"},{"internalType":"uint256","name":"_treasuryAmount","type":"uint256"},{"internalType":"address","name":"_operator","type":"address"},{"internalType":"uint256","name":"_operatorAmount","type":"uint256"},{"internalType":"address","name":"_tnftHolder","type":"address"},{"internalType":"uint256","name":"_tnftAmount","type":"uint256"},{"internalType":"address","name":"_bnftHolder","type":"address"},{"internalType":"uint256","name":"_bnftAmount","type":"uint256"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b506004805463ffffffff60401b19166bffffffff0000000000000000179055612a658061003e6000396000f3fe6080604052600436106101a55760003560e01c80637618ebbf116100e1578063c03afb591161008a578063c7fd170b11610064578063c7fd170b146104ac578063d1e3d5ba146104cc578063d742d6cb146104ec578063dbf75eda1461050c57600080fd5b8063c03afb5914610457578063c4d66de814610477578063c5bd77c01461049757600080fd5b8063acfc28f2116100bb578063acfc28f2146103e9578063b1c9fe6e1461040b578063bbf1e9971461044257600080fd5b80637618ebbf14610397578063940d559d146103ac578063a0be6dcf146103c957600080fd5b806335369dc41161014e5780635c60da1b116101285780635c60da1b146102ff5780635ec08baf146103145780636b8ee3181461034e5780637402a85d1461036e57600080fd5b806335369dc41461029757806346c9f30b1461029f5780634720dc46146102df57600080fd5b80632c8160b01161017f5780632c8160b01461024b5780632cab108b146102615780632e57fd5b1461028157600080fd5b8063089acd98146101b15780631bb2ca17146102085780631f0535b91461023657600080fd5b366101ac57005b600080fd5b3480156101bd57600080fd5b506000546101de9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021457600080fd5b5061022861022336600461226f565b61052c565b6040519081526020016101ff565b6102496102443660046122b4565b61069c565b005b34801561025757600080fd5b5061022860015481565b34801561026d57600080fd5b5061024961027c3660046122ef565b610708565b34801561028d57600080fd5b5061022860025481565b6102496109a3565b3480156102ab57600080fd5b506102bf6102ba36600461242b565b610ac7565b6040805194855260208501939093529183015260608201526080016101ff565b3480156102eb57600080fd5b506102bf6102fa3660046124a8565b610e18565b34801561030b57600080fd5b506101de6113e7565b34801561032057600080fd5b5060045461033990640100000000900463ffffffff1681565b60405163ffffffff90911681526020016101ff565b34801561035a57600080fd5b506102bf6103693660046124f8565b61149c565b34801561037a57600080fd5b506004546103399068010000000000000000900463ffffffff1681565b3480156103a357600080fd5b506102496115ee565b3480156103b857600080fd5b506004546103399063ffffffff1681565b3480156103d557600080fd5b506102496103e4366004612523565b61166d565b3480156103f557600080fd5b506103fe6116e5565b6040516101ff9190612595565b34801561041757600080fd5b50600454610435906c01000000000000000000000000900460ff1681565b6040516101ff9190612637565b34801561044e57600080fd5b50610249611773565b34801561046357600080fd5b50610249610472366004612678565b611813565b34801561048357600080fd5b50610249610492366004612699565b6118cb565b3480156104a357600080fd5b50610249611a12565b3480156104b857600080fd5b506102496104c73660046126b6565b611b01565b3480156104d857600080fd5b506102bf6104e73660046124f8565b611c0d565b3480156104f857600080fd5b506102496105073660046122b4565b611d3f565b34801561051857600080fd5b506102bf6105273660046126d1565b611e5a565b6000805473ffffffffffffffffffffffffffffffffffffffff1633146105995760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e747261637460448201526064015b60405180910390fd5b60045463ffffffff166000036105b157506000610695565b6004546000906105c79063ffffffff1684611f99565b905061016d8111156105ed5750506fffffffffffffffffffffffffffffffff8316610695565b6fffffffffffffffffffffffffffffffff85165b8115610674576000610614600784611fe1565b9050610621816064612856565b8161063767ffffffffffffffff89166064612862565b6106419190612856565b61064b9084612879565b61065591906128b6565b9150610662600784611fe1565b61066c9084612862565b925050610601565b610690816fffffffffffffffffffffffffffffffff8816612862565b925050505b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107035760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b600155565b60005473ffffffffffffffffffffffffffffffffffffffff16331461076f5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b60008673ffffffffffffffffffffffffffffffffffffffff168660405160006040518083038185875af1925050503d80600081146107c9576040519150601f19603f3d011682016040523d82523d6000602084013e6107ce565b606091505b509091505080156107e05760006107e2565b855b6107ec90896128f1565b97508473ffffffffffffffffffffffffffffffffffffffff168460405160006040518083038185875af1925050503d8060008114610846576040519150601f19603f3d011682016040523d82523d6000602084013e61084b565b606091505b5090915050801561085d57600061085f565b835b61086990896128f1565b97508273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146108c3576040519150601f19603f3d011682016040523d82523d6000602084013e6108c8565b606091505b509091505080156108da5760006108dc565b815b6108e690896128f1565b97508873ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114610940576040519150601f19603f3d011682016040523d82523d6000602084013e610945565b606091505b505080915050806109985760405162461bcd60e51b815260206004820152601460248201527f4661696c656420746f2073656e642045746865720000000000000000000000006044820152606401610590565b505050505050505050565b6109ab611ff7565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a4b5760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792070726f746f636f6c20726576656e7565206d616e6167657220636f60448201527f6e74726163742066756e6374696f6e00000000000000000000000000000000006064820152608401610590565b60025415610ac15760405162461bcd60e51b815260206004820152602e60248201527f616c72656164792072656365697665642074686520766573746564206175637460448201527f696f6e20666565207265776172640000000000000000000000000000000000006064820152608401610590565b34600255565b6000805481908190819073ffffffffffffffffffffffffffffffffffffffff163314610b355760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b60408051600480825260a082019092526000918291829182918291602082016080803683370190505090508f15610c8857610b708d8d61149c565b84600081518110610b8357610b83612909565b6020026020010185600181518110610b9d57610b9d612909565b6020026020010186600281518110610bb757610bb7612909565b6020026020010187600381518110610bd157610bd1612909565b6020908102919091010193909352929091529190525280518190600090610bfa57610bfa612909565b602002602001015185610c0d91906128f1565b945080600181518110610c2257610c22612909565b602002602001015184610c3591906128f1565b935080600281518110610c4a57610c4a612909565b602002602001015183610c5d91906128f1565b925080600381518110610c7257610c72612909565b602002602001015182610c8591906128f1565b91505b8e15610db057610c988b8b611c0d565b84600081518110610cab57610cab612909565b6020026020010185600181518110610cc557610cc5612909565b6020026020010186600281518110610cdf57610cdf612909565b6020026020010187600381518110610cf957610cf9612909565b6020908102919091010193909352929091529190525280518190600090610d2257610d22612909565b602002602001015185610d3591906128f1565b945080600181518110610d4a57610d4a612909565b602002602001015184610d5d91906128f1565b935080600281518110610d7257610d72612909565b602002602001015183610d8591906128f1565b925080600381518110610d9a57610d9a612909565b602002602001015182610dad91906128f1565b91505b8d15610e02576000610dc061208e565b905060006020610dd183601d612879565b610ddb91906128b6565b9050610de781876128f1565b9550610df38183612862565b610dfd90866128f1565b945050505b50929e919d509b50909950975050505050505050565b6000806000806000610e2861208e565b600254610e359190612862565b610e3f9047612862565b905067de0b6b3a76400000811015610ebf5760405162461bcd60e51b815260206004820152602660248201527f6e6f7420656e6f7567682062616c616e636520666f722066756c6c207769746860448201527f64726177616c00000000000000000000000000000000000000000000000000006064820152608401610590565b60036004546c01000000000000000000000000900460ff166005811115610ee857610ee8612608565b14610f355760405162461bcd60e51b815260206004820152601c60248201527f76616c696461746f72206e6f6465206973206e6f7420657869746564000000006044820152606401610590565b60408051600480825260a0820190925260009160208201608080368337019050509050610f6a6001600060018d8d8f8f610ac7565b84600081518110610f7d57610f7d612909565b6020026020010185600181518110610f9757610f97612909565b6020026020010186600281518110610fb157610fb1612909565b6020026020010187600381518110610fcb57610fcb612909565b60209081029190910101939093529290915291905252805181906003908110610ff657610ff6612909565b60200260200101518160028151811061101157611011612909565b60200260200101518260018151811061102c5761102c612909565b60200260200101518360008151811061104757611047612909565b602002602001015161105991906128f1565b61106391906128f1565b61106d91906128f1565b6110779083612862565b91506000806801b5267b1b18ce00008411156110a7576110a06801a055690d9db8000085612862565b915061110a565b680168d28e3f002800008411156110c8576714d1120d7b160000915061110a565b680161e232e52c7600008411156110fe576110ec84680168d28e3f00280000612862565b6110a0906714d1120d7b160000612862565b670de0b6b3a764000091505b6111148285612862565b9050808360018151811061112a5761112a612909565b6020026020010181815161113e91906128f1565b905250825182908490600290811061115857611158612909565b6020026020010181815161116c91906128f1565b905250600454600090611190908c908c90640100000000900463ffffffff1661052c565b905080846002815181106111a6576111a6612909565b602002602001018181516111ba9190612862565b9052506706f05b59d3b20000811115611241576706f05b59d3b20000846000815181106111e9576111e9612909565b602002602001018181516111fd91906128f1565b9052506112126706f05b59d3b2000082612862565b8460038151811061122557611225612909565b6020026020010181815161123991906128f1565b90525061126d565b808460008151811061125557611255612909565b6020026020010181815161126991906128f1565b9052505b61127561208e565b6002546112829190612862565b61128c9047612862565b8460038151811061129f5761129f612909565b6020026020010151856002815181106112ba576112ba612909565b6020026020010151866001815181106112d5576112d5612909565b6020026020010151876000815181106112f0576112f0612909565b602002602001015161130291906128f1565b61130c91906128f1565b61131691906128f1565b146113635760405162461bcd60e51b815260206004820152601060248201527f496e636f727265637420416d6f756e74000000000000000000000000000000006044820152606401610590565b8360008151811061137657611376612909565b60200260200101518460018151811061139157611391612909565b6020026020010151856002815181106113ac576113ac612909565b6020026020010151866003815181106113c7576113c7612909565b602002602001015198509850985098505050505050945094509450949050565b60008061141560017fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d51612862565b60001b905060008154905060008190508073ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114949190612938565b935050505090565b6000805481908190819073ffffffffffffffffffffffffffffffffffffffff16331461150a5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b6002544790600090821161151f57600061152c565b60025461152c9083612862565b90506801bc16d674ec8000008110611558576115516801bc16d674ec80000082612862565b905061157c565b676f05b59d3b200000811061157c57600080600080955095509550955050506115e5565b60008060008061158d858d8d611e5a565b6004549397509195509350915063ffffffff16156115d8576004546000906115bb9063ffffffff1642611f99565b9050600e81106115d6576115cf85836128f1565b9150600094505b505b9298509096509450925050505b92959194509250565b60005473ffffffffffffffffffffffffffffffffffffffff1633146116555760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b600061165f61208e565b111561166b5760006002555b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146116d45760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b6116e060038383612166565b505050565b600380546116f290612955565b80601f016020809104026020016040519081016040528092919081815260200182805461171e90612955565b801561176b5780601f106117405761010080835404028352916020019161176b565b820191906000526020600020905b81548152906001019060200180831161174e57829003601f168201915b505050505081565b60005473ffffffffffffffffffffffffffffffffffffffff1633146117da5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b600480547fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff166c05000000000000000000000000179055565b60005473ffffffffffffffffffffffffffffffffffffffff16331461187a5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b600480548291907fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff166c010000000000000000000000008360058111156118c3576118c3612608565b021790555050565b60045468010000000000000000900463ffffffff161561192d5760405162461bcd60e51b815260206004820152601360248201527f616c726561647920696e697469616c69736564000000000000000000000000006044820152606401610590565b73ffffffffffffffffffffffffffffffffffffffff81166119905760405162461bcd60e51b815260206004820152601160248201527f4e6f207a65726f206164647265737365730000000000000000000000000000006044820152606401610590565b600480547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff16680100000000000000004263ffffffff1602179055600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a795760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b60045463ffffffff1615611acf5760405162461bcd60e51b815260206004820152601e60248201527f4578697420726571756573742077617320616c72656164792073656e742e00006044820152606401610590565b600480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000164263ffffffff16179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314611b685760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b428163ffffffff161115611bbe5760405162461bcd60e51b815260206004820152601560248201527f496e76616c696420657869742074696d6573616d7000000000000000000000006044820152606401610590565b600480546c0300000000000000000000000063ffffffff93909316640100000000027fffffffffffffffffffffffffffffffffffffff00ffffffff00000000ffffffff90911617919091179055565b6000805481908190819073ffffffffffffffffffffffffffffffffffffffff163314611c7b5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b600154600003611c96575060009250829150819050806115e5565b6000611ca0611ff7565b73ffffffffffffffffffffffffffffffffffffffff166366f8a32b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0e91906129a8565b9050600060015482611d209190612862565b9050611d2d818989611e5a565b929b919a509850909650945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611da65760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b6000805460405173ffffffffffffffffffffffffffffffffffffffff9091169083908381818185875af1925050503d8060008114611e00576040519150601f19603f3d011682016040523d82523d6000602084013e611e05565b606091505b5050905080611e565760405162461bcd60e51b815260206004820152601460248201527f4661696c656420746f2073656e642045746865720000000000000000000000006044820152606401610590565b5050565b600080600080848660000151876060015188604001518960200151611e7f91906129c1565b611e8991906129c1565b611e9391906129c1565b67ffffffffffffffff1614611eea5760405162461bcd60e51b815260206004820152601060248201527f496e636f72726563742053706c697473000000000000000000000000000000006044820152606401610590565b600085876020015167ffffffffffffffff1689611f079190612879565b611f1191906128b6565b9050600086886040015167ffffffffffffffff168a611f309190612879565b611f3a91906128b6565b9050600087896060015167ffffffffffffffff168b611f599190612879565b611f6391906128b6565b9050600083611f7284846128f1565b611f7c91906128f1565b611f86908c612862565b939b929a50909850919650945050505050565b60008263ffffffff168263ffffffff1611611fb657506000611fdb565b6000611fc284846129ed565b63ffffffff169050611fd762015180826128b6565b9150505b92915050565b6000818310611ff05781610695565b5090919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166359435fe76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612065573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120899190612938565b905090565b60006002546000036120a05750600090565b60006120aa611ff7565b73ffffffffffffffffffffffffffffffffffffffff1663e9c074586040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121189190612a12565b6fffffffffffffffffffffffffffffffff169050600061214a600460089054906101000a900463ffffffff1642611f99565b905081811061215d576002549250505090565b60009250505090565b82805461217290612955565b90600052602060002090601f01602090048101928261219457600085556121f8565b82601f106121cb578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008235161785556121f8565b828001600101855582156121f8579182015b828111156121f85782358255916020019190600101906121dd565b50612204929150612208565b5090565b5b808211156122045760008155600101612209565b6fffffffffffffffffffffffffffffffff8116811461223b57600080fd5b50565b803567ffffffffffffffff8116811461225657600080fd5b919050565b803563ffffffff8116811461225657600080fd5b60008060006060848603121561228457600080fd5b833561228f8161221d565b925061229d6020850161223e565b91506122ab6040850161225b565b90509250925092565b6000602082840312156122c657600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461223b57600080fd5b600080600080600080600080610100898b03121561230c57600080fd5b8835612317816122cd565b975060208901359650604089013561232e816122cd565b9550606089013594506080890135612345816122cd565b935060a0890135925060c089013561235c816122cd565b8092505060e089013590509295985092959890939650565b8035801515811461225657600080fd5b60006080828403121561239657600080fd5b6040516080810181811067ffffffffffffffff821117156123e0577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040529050806123ef8361223e565b81526123fd6020840161223e565b602082015261240e6040840161223e565b604082015261241f6060840161223e565b60608201525092915050565b60008060008060008060006101a0888a03121561244757600080fd5b61245088612374565b965061245e60208901612374565b955061246c60408901612374565b945061247b8960608a01612384565b935060e08801359250612492896101008a01612384565b9150610180880135905092959891949750929550565b60008060008060e085870312156124be57600080fd5b6124c88686612384565b93506080850135925060a08501356124df8161221d565b91506124ed60c0860161223e565b905092959194509250565b60008060a0838503121561250b57600080fd5b6125158484612384565b946080939093013593505050565b6000806020838503121561253657600080fd5b823567ffffffffffffffff8082111561254e57600080fd5b818501915085601f83011261256257600080fd5b81358181111561257157600080fd5b86602082850101111561258357600080fd5b60209290920196919550909350505050565b600060208083528351808285015260005b818110156125c2578581018301518582016040015282016125a6565b818111156125d4576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160068310612672577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60006020828403121561268a57600080fd5b81356006811061069557600080fd5b6000602082840312156126ab57600080fd5b8135610695816122cd565b6000602082840312156126c857600080fd5b6106958261225b565b600080600060c084860312156126e657600080fd5b833592506126f78560208601612384565b915060a084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600181815b8085111561278f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561277557612775612707565b8085161561278257918102915b93841c939080029061273b565b509250929050565b6000826127a657506001611fdb565b816127b357506000611fdb565b81600181146127c957600281146127d3576127ef565b6001915050611fdb565b60ff8411156127e4576127e4612707565b50506001821b611fdb565b5060208310610133831016604e8410600b8410161715612812575081810a611fdb565b61281c8383612736565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561284e5761284e612707565b029392505050565b60006106958383612797565b60008282101561287457612874612707565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156128b1576128b1612707565b500290565b6000826128ec577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000821982111561290457612904612707565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561294a57600080fd5b8151610695816122cd565b600181811c9082168061296957607f821691505b6020821081036129a2577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000602082840312156129ba57600080fd5b5051919050565b600067ffffffffffffffff8083168185168083038211156129e4576129e4612707565b01949350505050565b600063ffffffff83811690831681811015612a0a57612a0a612707565b039392505050565b600060208284031215612a2457600080fd5b81516106958161221d56fea2646970667358221220905c18f9d6d4e1b6ed1411572cdc43f9f542673c32c71d3951c87a0018002fd064736f6c634300080d0033
Deployed Bytecode
0x6080604052600436106101a55760003560e01c80637618ebbf116100e1578063c03afb591161008a578063c7fd170b11610064578063c7fd170b146104ac578063d1e3d5ba146104cc578063d742d6cb146104ec578063dbf75eda1461050c57600080fd5b8063c03afb5914610457578063c4d66de814610477578063c5bd77c01461049757600080fd5b8063acfc28f2116100bb578063acfc28f2146103e9578063b1c9fe6e1461040b578063bbf1e9971461044257600080fd5b80637618ebbf14610397578063940d559d146103ac578063a0be6dcf146103c957600080fd5b806335369dc41161014e5780635c60da1b116101285780635c60da1b146102ff5780635ec08baf146103145780636b8ee3181461034e5780637402a85d1461036e57600080fd5b806335369dc41461029757806346c9f30b1461029f5780634720dc46146102df57600080fd5b80632c8160b01161017f5780632c8160b01461024b5780632cab108b146102615780632e57fd5b1461028157600080fd5b8063089acd98146101b15780631bb2ca17146102085780631f0535b91461023657600080fd5b366101ac57005b600080fd5b3480156101bd57600080fd5b506000546101de9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561021457600080fd5b5061022861022336600461226f565b61052c565b6040519081526020016101ff565b6102496102443660046122b4565b61069c565b005b34801561025757600080fd5b5061022860015481565b34801561026d57600080fd5b5061024961027c3660046122ef565b610708565b34801561028d57600080fd5b5061022860025481565b6102496109a3565b3480156102ab57600080fd5b506102bf6102ba36600461242b565b610ac7565b6040805194855260208501939093529183015260608201526080016101ff565b3480156102eb57600080fd5b506102bf6102fa3660046124a8565b610e18565b34801561030b57600080fd5b506101de6113e7565b34801561032057600080fd5b5060045461033990640100000000900463ffffffff1681565b60405163ffffffff90911681526020016101ff565b34801561035a57600080fd5b506102bf6103693660046124f8565b61149c565b34801561037a57600080fd5b506004546103399068010000000000000000900463ffffffff1681565b3480156103a357600080fd5b506102496115ee565b3480156103b857600080fd5b506004546103399063ffffffff1681565b3480156103d557600080fd5b506102496103e4366004612523565b61166d565b3480156103f557600080fd5b506103fe6116e5565b6040516101ff9190612595565b34801561041757600080fd5b50600454610435906c01000000000000000000000000900460ff1681565b6040516101ff9190612637565b34801561044e57600080fd5b50610249611773565b34801561046357600080fd5b50610249610472366004612678565b611813565b34801561048357600080fd5b50610249610492366004612699565b6118cb565b3480156104a357600080fd5b50610249611a12565b3480156104b857600080fd5b506102496104c73660046126b6565b611b01565b3480156104d857600080fd5b506102bf6104e73660046124f8565b611c0d565b3480156104f857600080fd5b506102496105073660046122b4565b611d3f565b34801561051857600080fd5b506102bf6105273660046126d1565b611e5a565b6000805473ffffffffffffffffffffffffffffffffffffffff1633146105995760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e747261637460448201526064015b60405180910390fd5b60045463ffffffff166000036105b157506000610695565b6004546000906105c79063ffffffff1684611f99565b905061016d8111156105ed5750506fffffffffffffffffffffffffffffffff8316610695565b6fffffffffffffffffffffffffffffffff85165b8115610674576000610614600784611fe1565b9050610621816064612856565b8161063767ffffffffffffffff89166064612862565b6106419190612856565b61064b9084612879565b61065591906128b6565b9150610662600784611fe1565b61066c9084612862565b925050610601565b610690816fffffffffffffffffffffffffffffffff8816612862565b925050505b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107035760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b600155565b60005473ffffffffffffffffffffffffffffffffffffffff16331461076f5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b60008673ffffffffffffffffffffffffffffffffffffffff168660405160006040518083038185875af1925050503d80600081146107c9576040519150601f19603f3d011682016040523d82523d6000602084013e6107ce565b606091505b509091505080156107e05760006107e2565b855b6107ec90896128f1565b97508473ffffffffffffffffffffffffffffffffffffffff168460405160006040518083038185875af1925050503d8060008114610846576040519150601f19603f3d011682016040523d82523d6000602084013e61084b565b606091505b5090915050801561085d57600061085f565b835b61086990896128f1565b97508273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146108c3576040519150601f19603f3d011682016040523d82523d6000602084013e6108c8565b606091505b509091505080156108da5760006108dc565b815b6108e690896128f1565b97508873ffffffffffffffffffffffffffffffffffffffff168860405160006040518083038185875af1925050503d8060008114610940576040519150601f19603f3d011682016040523d82523d6000602084013e610945565b606091505b505080915050806109985760405162461bcd60e51b815260206004820152601460248201527f4661696c656420746f2073656e642045746865720000000000000000000000006044820152606401610590565b505050505050505050565b6109ab611ff7565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a4b5760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792070726f746f636f6c20726576656e7565206d616e6167657220636f60448201527f6e74726163742066756e6374696f6e00000000000000000000000000000000006064820152608401610590565b60025415610ac15760405162461bcd60e51b815260206004820152602e60248201527f616c72656164792072656365697665642074686520766573746564206175637460448201527f696f6e20666565207265776172640000000000000000000000000000000000006064820152608401610590565b34600255565b6000805481908190819073ffffffffffffffffffffffffffffffffffffffff163314610b355760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b60408051600480825260a082019092526000918291829182918291602082016080803683370190505090508f15610c8857610b708d8d61149c565b84600081518110610b8357610b83612909565b6020026020010185600181518110610b9d57610b9d612909565b6020026020010186600281518110610bb757610bb7612909565b6020026020010187600381518110610bd157610bd1612909565b6020908102919091010193909352929091529190525280518190600090610bfa57610bfa612909565b602002602001015185610c0d91906128f1565b945080600181518110610c2257610c22612909565b602002602001015184610c3591906128f1565b935080600281518110610c4a57610c4a612909565b602002602001015183610c5d91906128f1565b925080600381518110610c7257610c72612909565b602002602001015182610c8591906128f1565b91505b8e15610db057610c988b8b611c0d565b84600081518110610cab57610cab612909565b6020026020010185600181518110610cc557610cc5612909565b6020026020010186600281518110610cdf57610cdf612909565b6020026020010187600381518110610cf957610cf9612909565b6020908102919091010193909352929091529190525280518190600090610d2257610d22612909565b602002602001015185610d3591906128f1565b945080600181518110610d4a57610d4a612909565b602002602001015184610d5d91906128f1565b935080600281518110610d7257610d72612909565b602002602001015183610d8591906128f1565b925080600381518110610d9a57610d9a612909565b602002602001015182610dad91906128f1565b91505b8d15610e02576000610dc061208e565b905060006020610dd183601d612879565b610ddb91906128b6565b9050610de781876128f1565b9550610df38183612862565b610dfd90866128f1565b945050505b50929e919d509b50909950975050505050505050565b6000806000806000610e2861208e565b600254610e359190612862565b610e3f9047612862565b905067de0b6b3a76400000811015610ebf5760405162461bcd60e51b815260206004820152602660248201527f6e6f7420656e6f7567682062616c616e636520666f722066756c6c207769746860448201527f64726177616c00000000000000000000000000000000000000000000000000006064820152608401610590565b60036004546c01000000000000000000000000900460ff166005811115610ee857610ee8612608565b14610f355760405162461bcd60e51b815260206004820152601c60248201527f76616c696461746f72206e6f6465206973206e6f7420657869746564000000006044820152606401610590565b60408051600480825260a0820190925260009160208201608080368337019050509050610f6a6001600060018d8d8f8f610ac7565b84600081518110610f7d57610f7d612909565b6020026020010185600181518110610f9757610f97612909565b6020026020010186600281518110610fb157610fb1612909565b6020026020010187600381518110610fcb57610fcb612909565b60209081029190910101939093529290915291905252805181906003908110610ff657610ff6612909565b60200260200101518160028151811061101157611011612909565b60200260200101518260018151811061102c5761102c612909565b60200260200101518360008151811061104757611047612909565b602002602001015161105991906128f1565b61106391906128f1565b61106d91906128f1565b6110779083612862565b91506000806801b5267b1b18ce00008411156110a7576110a06801a055690d9db8000085612862565b915061110a565b680168d28e3f002800008411156110c8576714d1120d7b160000915061110a565b680161e232e52c7600008411156110fe576110ec84680168d28e3f00280000612862565b6110a0906714d1120d7b160000612862565b670de0b6b3a764000091505b6111148285612862565b9050808360018151811061112a5761112a612909565b6020026020010181815161113e91906128f1565b905250825182908490600290811061115857611158612909565b6020026020010181815161116c91906128f1565b905250600454600090611190908c908c90640100000000900463ffffffff1661052c565b905080846002815181106111a6576111a6612909565b602002602001018181516111ba9190612862565b9052506706f05b59d3b20000811115611241576706f05b59d3b20000846000815181106111e9576111e9612909565b602002602001018181516111fd91906128f1565b9052506112126706f05b59d3b2000082612862565b8460038151811061122557611225612909565b6020026020010181815161123991906128f1565b90525061126d565b808460008151811061125557611255612909565b6020026020010181815161126991906128f1565b9052505b61127561208e565b6002546112829190612862565b61128c9047612862565b8460038151811061129f5761129f612909565b6020026020010151856002815181106112ba576112ba612909565b6020026020010151866001815181106112d5576112d5612909565b6020026020010151876000815181106112f0576112f0612909565b602002602001015161130291906128f1565b61130c91906128f1565b61131691906128f1565b146113635760405162461bcd60e51b815260206004820152601060248201527f496e636f727265637420416d6f756e74000000000000000000000000000000006044820152606401610590565b8360008151811061137657611376612909565b60200260200101518460018151811061139157611391612909565b6020026020010151856002815181106113ac576113ac612909565b6020026020010151866003815181106113c7576113c7612909565b602002602001015198509850985098505050505050945094509450949050565b60008061141560017fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d51612862565b60001b905060008154905060008190508073ffffffffffffffffffffffffffffffffffffffff16635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114949190612938565b935050505090565b6000805481908190819073ffffffffffffffffffffffffffffffffffffffff16331461150a5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b6002544790600090821161151f57600061152c565b60025461152c9083612862565b90506801bc16d674ec8000008110611558576115516801bc16d674ec80000082612862565b905061157c565b676f05b59d3b200000811061157c57600080600080955095509550955050506115e5565b60008060008061158d858d8d611e5a565b6004549397509195509350915063ffffffff16156115d8576004546000906115bb9063ffffffff1642611f99565b9050600e81106115d6576115cf85836128f1565b9150600094505b505b9298509096509450925050505b92959194509250565b60005473ffffffffffffffffffffffffffffffffffffffff1633146116555760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b600061165f61208e565b111561166b5760006002555b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146116d45760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b6116e060038383612166565b505050565b600380546116f290612955565b80601f016020809104026020016040519081016040528092919081815260200182805461171e90612955565b801561176b5780601f106117405761010080835404028352916020019161176b565b820191906000526020600020905b81548152906001019060200180831161174e57829003601f168201915b505050505081565b60005473ffffffffffffffffffffffffffffffffffffffff1633146117da5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b600480547fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff166c05000000000000000000000000179055565b60005473ffffffffffffffffffffffffffffffffffffffff16331461187a5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b600480548291907fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff166c010000000000000000000000008360058111156118c3576118c3612608565b021790555050565b60045468010000000000000000900463ffffffff161561192d5760405162461bcd60e51b815260206004820152601360248201527f616c726561647920696e697469616c69736564000000000000000000000000006044820152606401610590565b73ffffffffffffffffffffffffffffffffffffffff81166119905760405162461bcd60e51b815260206004820152601160248201527f4e6f207a65726f206164647265737365730000000000000000000000000000006044820152606401610590565b600480547fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff16680100000000000000004263ffffffff1602179055600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a795760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b60045463ffffffff1615611acf5760405162461bcd60e51b815260206004820152601e60248201527f4578697420726571756573742077617320616c72656164792073656e742e00006044820152606401610590565b600480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000164263ffffffff16179055565b60005473ffffffffffffffffffffffffffffffffffffffff163314611b685760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b428163ffffffff161115611bbe5760405162461bcd60e51b815260206004820152601560248201527f496e76616c696420657869742074696d6573616d7000000000000000000000006044820152606401610590565b600480546c0300000000000000000000000063ffffffff93909316640100000000027fffffffffffffffffffffffffffffffffffffff00ffffffff00000000ffffffff90911617919091179055565b6000805481908190819073ffffffffffffffffffffffffffffffffffffffff163314611c7b5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b600154600003611c96575060009250829150819050806115e5565b6000611ca0611ff7565b73ffffffffffffffffffffffffffffffffffffffff166366f8a32b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611cea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0e91906129a8565b9050600060015482611d209190612862565b9050611d2d818989611e5a565b929b919a509850909650945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611da65760405162461bcd60e51b815260206004820181905260248201527f4f6e6c7920457468657246694e6f64654d616e6167657220436f6e74726163746044820152606401610590565b6000805460405173ffffffffffffffffffffffffffffffffffffffff9091169083908381818185875af1925050503d8060008114611e00576040519150601f19603f3d011682016040523d82523d6000602084013e611e05565b606091505b5050905080611e565760405162461bcd60e51b815260206004820152601460248201527f4661696c656420746f2073656e642045746865720000000000000000000000006044820152606401610590565b5050565b600080600080848660000151876060015188604001518960200151611e7f91906129c1565b611e8991906129c1565b611e9391906129c1565b67ffffffffffffffff1614611eea5760405162461bcd60e51b815260206004820152601060248201527f496e636f72726563742053706c697473000000000000000000000000000000006044820152606401610590565b600085876020015167ffffffffffffffff1689611f079190612879565b611f1191906128b6565b9050600086886040015167ffffffffffffffff168a611f309190612879565b611f3a91906128b6565b9050600087896060015167ffffffffffffffff168b611f599190612879565b611f6391906128b6565b9050600083611f7284846128f1565b611f7c91906128f1565b611f86908c612862565b939b929a50909850919650945050505050565b60008263ffffffff168263ffffffff1611611fb657506000611fdb565b6000611fc284846129ed565b63ffffffff169050611fd762015180826128b6565b9150505b92915050565b6000818310611ff05781610695565b5090919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166359435fe76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612065573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120899190612938565b905090565b60006002546000036120a05750600090565b60006120aa611ff7565b73ffffffffffffffffffffffffffffffffffffffff1663e9c074586040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121189190612a12565b6fffffffffffffffffffffffffffffffff169050600061214a600460089054906101000a900463ffffffff1642611f99565b905081811061215d576002549250505090565b60009250505090565b82805461217290612955565b90600052602060002090601f01602090048101928261219457600085556121f8565b82601f106121cb578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008235161785556121f8565b828001600101855582156121f8579182015b828111156121f85782358255916020019190600101906121dd565b50612204929150612208565b5090565b5b808211156122045760008155600101612209565b6fffffffffffffffffffffffffffffffff8116811461223b57600080fd5b50565b803567ffffffffffffffff8116811461225657600080fd5b919050565b803563ffffffff8116811461225657600080fd5b60008060006060848603121561228457600080fd5b833561228f8161221d565b925061229d6020850161223e565b91506122ab6040850161225b565b90509250925092565b6000602082840312156122c657600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461223b57600080fd5b600080600080600080600080610100898b03121561230c57600080fd5b8835612317816122cd565b975060208901359650604089013561232e816122cd565b9550606089013594506080890135612345816122cd565b935060a0890135925060c089013561235c816122cd565b8092505060e089013590509295985092959890939650565b8035801515811461225657600080fd5b60006080828403121561239657600080fd5b6040516080810181811067ffffffffffffffff821117156123e0577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040529050806123ef8361223e565b81526123fd6020840161223e565b602082015261240e6040840161223e565b604082015261241f6060840161223e565b60608201525092915050565b60008060008060008060006101a0888a03121561244757600080fd5b61245088612374565b965061245e60208901612374565b955061246c60408901612374565b945061247b8960608a01612384565b935060e08801359250612492896101008a01612384565b9150610180880135905092959891949750929550565b60008060008060e085870312156124be57600080fd5b6124c88686612384565b93506080850135925060a08501356124df8161221d565b91506124ed60c0860161223e565b905092959194509250565b60008060a0838503121561250b57600080fd5b6125158484612384565b946080939093013593505050565b6000806020838503121561253657600080fd5b823567ffffffffffffffff8082111561254e57600080fd5b818501915085601f83011261256257600080fd5b81358181111561257157600080fd5b86602082850101111561258357600080fd5b60209290920196919550909350505050565b600060208083528351808285015260005b818110156125c2578581018301518582016040015282016125a6565b818111156125d4576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160068310612672577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60006020828403121561268a57600080fd5b81356006811061069557600080fd5b6000602082840312156126ab57600080fd5b8135610695816122cd565b6000602082840312156126c857600080fd5b6106958261225b565b600080600060c084860312156126e657600080fd5b833592506126f78560208601612384565b915060a084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600181815b8085111561278f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561277557612775612707565b8085161561278257918102915b93841c939080029061273b565b509250929050565b6000826127a657506001611fdb565b816127b357506000611fdb565b81600181146127c957600281146127d3576127ef565b6001915050611fdb565b60ff8411156127e4576127e4612707565b50506001821b611fdb565b5060208310610133831016604e8410600b8410161715612812575081810a611fdb565b61281c8383612736565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561284e5761284e612707565b029392505050565b60006106958383612797565b60008282101561287457612874612707565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156128b1576128b1612707565b500290565b6000826128ec577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000821982111561290457612904612707565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561294a57600080fd5b8151610695816122cd565b600181811c9082168061296957607f821691505b6020821081036129a2577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000602082840312156129ba57600080fd5b5051919050565b600067ffffffffffffffff8083168185168083038211156129e4576129e4612707565b01949350505050565b600063ffffffff83811690831681811015612a0a57612a0a612707565b039392505050565b600060208284031215612a2457600080fd5b81516106958161221d56fea2646970667358221220905c18f9d6d4e1b6ed1411572cdc43f9f542673c32c71d3951c87a0018002fd064736f6c634300080d0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.