Token Liquid staked Ether 2.0
Overview [ERC-20]
Max Total Supply:
1,660.765385797178541478 stETH
Holders:
159
Transfers:
-
Profile Summary
Contract:
Decimals:
18
[ Download CSV Export ]
[ Download CSV Export ]
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Lido
Compiler Version
v0.4.24+commit.e67f0147
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-06-08 */ // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.4.24; // Part: GNSPS/[email protected]/BytesLib library BytesLib { function concat(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bytes) { bytes memory tempBytes; assembly { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // Store the length of the first bytes array at the beginning of // the memory for tempBytes. let length := mload(_preBytes) mstore(tempBytes, length) // Maintain a memory counter for the current write location in the // temp bytes array by adding the 32 bytes for the array length to // the starting location. let mc := add(tempBytes, 0x20) // Stop copying when the memory counter reaches the length of the // first bytes array. let end := add(mc, length) for { // Initialize a copy counter to the start of the _preBytes data, // 32 bytes into its memory. let cc := add(_preBytes, 0x20) } lt(mc, end) { // Increase both counters by 32 bytes each iteration. mc := add(mc, 0x20) cc := add(cc, 0x20) } { // Write the _preBytes data into the tempBytes memory 32 bytes // at a time. mstore(mc, mload(cc)) } // Add the length of _postBytes to the current length of tempBytes // and store it as the new length in the first 32 bytes of the // tempBytes memory. length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) // Move the memory counter back from a multiple of 0x20 to the // actual end of the _preBytes data. mc := end // Stop copying when the memory counter reaches the new combined // length of the arrays. end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } // Update the free-memory pointer by padding our last write location // to 32 bytes: add 31 bytes to the end of tempBytes to move to the // next 32 byte block, then round down to the nearest multiple of // 32. If the sum of the length of the two arrays is zero then add // one before rounding down to leave a blank 32 bytes (the length block with 0). mstore(0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) // Round down to the nearest 32 bytes. )) } return tempBytes; } function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal { assembly { // Read the first 32 bytes of _preBytes storage, which is the length // of the array. (We don't need to use the offset into the slot // because arrays use the entire slot.) let fslot := sload(_preBytes_slot) // Arrays of 31 bytes or less have an even value in their slot, // while longer arrays have an odd value. The actual length is // the slot divided by two for odd values, and the lowest order // byte divided by two for even values. // If the slot is even, bitwise and the slot with 255 and divide by // two to get the length. If the slot is odd, bitwise and the slot // with -1 and divide by two. let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) let newlength := add(slength, mlength) // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage switch add(lt(slength, 32), lt(newlength, 32)) case 2 { // Since the new array still fits in the slot, we just need to // update the contents of the slot. // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length sstore( _preBytes_slot, // all the modifications to the slot are inside this // next block add( // we can just add to the slot contents because the // bytes we want to change are the LSBs fslot, add( mul( div( // load the bytes from memory mload(add(_postBytes, 0x20)), // zero all bytes to the right exp(0x100, sub(32, mlength)) ), // and now shift left the number of bytes to // leave space for the length in the slot exp(0x100, sub(32, newlength)) ), // increase length by the double of the memory // bytes length mul(mlength, 2) ) ) ) } case 1 { // The stored value fits in the slot, but the combined value // will exceed it. // get the keccak hash to get the contents of the array mstore(0x0, _preBytes_slot) let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes_slot, add(mul(newlength, 2), 1)) // The contents of the _postBytes array start 32 bytes into // the structure. Our first read should obtain the `submod` // bytes that can fit into the unused space in the last word // of the stored array. To get this, we read 32 bytes starting // from `submod`, so the data we read overlaps with the array // contents by `submod` bytes. Masking the lowest-order // `submod` bytes allows us to add that value directly to the // stored value. let submod := sub(32, slength) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore( sc, add( and( fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00 ), and(mload(mc), mask) ) ) for { mc := add(mc, 0x20) sc := add(sc, 1) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } default { // get the keccak hash to get the contents of the array mstore(0x0, _preBytes_slot) // Start copying to the last used word of the stored array. let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes_slot, add(mul(newlength, 2), 1)) // Copy over the first `submod` bytes of the new data as in // case 1 above. let slengthmod := mod(slength, 32) let mlengthmod := mod(mlength, 32) let submod := sub(32, slengthmod) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore(sc, add(sload(sc), and(mload(mc), mask))) for { sc := add(sc, 1) mc := add(mc, 0x20) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } } } function slice(bytes _bytes, uint _start, uint _length) internal pure returns (bytes) { require(_bytes.length >= (_start + _length)); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes _bytes, uint _start) internal pure returns (address) { require(_bytes.length >= (_start + 20)); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint8(bytes _bytes, uint _start) internal pure returns (uint8) { require(_bytes.length >= (_start + 1)); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes _bytes, uint _start) internal pure returns (uint16) { require(_bytes.length >= (_start + 2)); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint32(bytes _bytes, uint _start) internal pure returns (uint32) { require(_bytes.length >= (_start + 4)); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint(bytes _bytes, uint _start) internal pure returns (uint256) { require(_bytes.length >= (_start + 32)); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes32(bytes _bytes, uint _start) internal pure returns (bytes32) { require(_bytes.length >= (_start + 32)); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { bool success = true; assembly { let length := mload(_preBytes) // if lengths don't match the arrays are not equal switch eq(length, mload(_postBytes)) case 1 { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 let mc := add(_preBytes, 0x20) let end := add(mc, length) for { let cc := add(_postBytes, 0x20) // the next line is the loop condition: // while(uint(mc < end) + cb == 2) } eq(add(lt(mc, end), cb), 2) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { // if any of these checks fails then arrays are not equal if iszero(eq(mload(mc), mload(cc))) { // unsuccess: success := 0 cb := 0 } } } default { // unsuccess: success := 0 } } return success; } function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) { bool success = true; assembly { // we know _preBytes_offset is 0 let fslot := sload(_preBytes_slot) // Decode the length of the stored array like in concatStorage(). let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) // if lengths don't match the arrays are not equal switch eq(slength, mlength) case 1 { // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage if iszero(iszero(slength)) { switch lt(slength, 32) case 1 { // blank the last byte which is the length fslot := mul(div(fslot, 0x100), 0x100) if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { // unsuccess: success := 0 } } default { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 // get the keccak hash to get the contents of the array mstore(0x0, _preBytes_slot) let sc := keccak256(0x0, 0x20) let mc := add(_postBytes, 0x20) let end := add(mc, mlength) // the next line is the loop condition: // while(uint(mc < end) + cb == 2) for {} eq(add(lt(mc, end), cb), 2) { sc := add(sc, 1) mc := add(mc, 0x20) } { if iszero(eq(sload(sc), mload(mc))) { // unsuccess: success := 0 cb := 0 } } } } } default { // unsuccess: success := 0 } } return success; } } // Part: IDepositContract /** * @title Deposit contract interface */ interface IDepositContract { /** * @notice Top-ups deposit of a validator on the ETH 2.0 side * @param pubkey Validator signing key * @param withdrawal_credentials Credentials that allows to withdraw funds * @param signature Signature of the request * @param deposit_data_root The deposits Merkle tree node, used as a checksum */ function deposit( bytes /* 48 */ pubkey, bytes /* 32 */ withdrawal_credentials, bytes /* 96 */ signature, bytes32 deposit_data_root ) external payable; } // Part: INodeOperatorsRegistry /** * @title Node Operator registry * * Node Operator registry manages signing keys and other node operator data. * It's also responsible for distributing rewards to node operators. */ interface INodeOperatorsRegistry { /** * @notice Add node operator named `name` with reward address `rewardAddress` and staking limit `stakingLimit` validators * @param _name Human-readable name * @param _rewardAddress Ethereum 1 address which receives stETH rewards for this operator * @param _stakingLimit the maximum number of validators to stake for this operator * @return a unique key of the added operator */ function addNodeOperator(string _name, address _rewardAddress, uint64 _stakingLimit) external returns (uint256 id); /** * @notice `_active ? 'Enable' : 'Disable'` the node operator #`_id` */ function setNodeOperatorActive(uint256 _id, bool _active) external; /** * @notice Change human-readable name of the node operator #`_id` to `_name` */ function setNodeOperatorName(uint256 _id, string _name) external; /** * @notice Change reward address of the node operator #`_id` to `_rewardAddress` */ function setNodeOperatorRewardAddress(uint256 _id, address _rewardAddress) external; /** * @notice Set the maximum number of validators to stake for the node operator #`_id` to `_stakingLimit` */ function setNodeOperatorStakingLimit(uint256 _id, uint64 _stakingLimit) external; /** * @notice Report `_stoppedIncrement` more stopped validators of the node operator #`_id` */ function reportStoppedValidators(uint256 _id, uint64 _stoppedIncrement) external; /** * @notice Remove unused signing keys * @dev Function is used by the pool */ function trimUnusedKeys() external; /** * @notice Returns total number of node operators */ function getNodeOperatorsCount() external view returns (uint256); /** * @notice Returns number of active node operators */ function getActiveNodeOperatorsCount() external view returns (uint256); /** * @notice Returns the n-th node operator * @param _id Node Operator id * @param _fullInfo If true, name will be returned as well */ function getNodeOperator(uint256 _id, bool _fullInfo) external view returns ( bool active, string name, address rewardAddress, uint64 stakingLimit, uint64 stoppedValidators, uint64 totalSigningKeys, uint64 usedSigningKeys); /** * @notice Returns the rewards distribution proportional to the effective stake for each node operator. * @param _totalRewardShares Total amount of reward shares to distribute. */ function getRewardsDistribution(uint256 _totalRewardShares) external view returns ( address[] memory recipients, uint256[] memory shares ); event NodeOperatorAdded(uint256 id, string name, address rewardAddress, uint64 stakingLimit); event NodeOperatorActiveSet(uint256 indexed id, bool active); event NodeOperatorNameSet(uint256 indexed id, string name); event NodeOperatorRewardAddressSet(uint256 indexed id, address rewardAddress); event NodeOperatorStakingLimitSet(uint256 indexed id, uint64 stakingLimit); event NodeOperatorTotalStoppedValidatorsReported(uint256 indexed id, uint64 totalStopped); /** * @notice Selects and returns at most `_numKeys` signing keys (as well as the corresponding * signatures) from the set of active keys and marks the selected keys as used. * May only be called by the pool contract. * * @param _numKeys The number of keys to select. The actual number of selected keys may be less * due to the lack of active keys. */ function assignNextSigningKeys(uint256 _numKeys) external returns (bytes memory pubkeys, bytes memory signatures); /** * @notice Add `_quantity` validator signing keys to the keys of the node operator #`_operator_id`. Concatenated keys are: `_pubkeys` * @dev Along with each key the DAO has to provide a signatures for the * (pubkey, withdrawal_credentials, 32000000000) message. * Given that information, the contract'll be able to call * deposit_contract.deposit on-chain. * @param _operator_id Node Operator id * @param _quantity Number of signing keys provided * @param _pubkeys Several concatenated validator signing keys * @param _signatures Several concatenated signatures for (pubkey, withdrawal_credentials, 32000000000) messages */ function addSigningKeys(uint256 _operator_id, uint256 _quantity, bytes _pubkeys, bytes _signatures) external; /** * @notice Removes a validator signing key #`_index` from the keys of the node operator #`_operator_id` * @param _operator_id Node Operator id * @param _index Index of the key, starting with 0 */ function removeSigningKey(uint256 _operator_id, uint256 _index) external; /** * @notice Returns total number of signing keys of the node operator #`_operator_id` */ function getTotalSigningKeyCount(uint256 _operator_id) external view returns (uint256); /** * @notice Returns number of usable signing keys of the node operator #`_operator_id` */ function getUnusedSigningKeyCount(uint256 _operator_id) external view returns (uint256); /** * @notice Returns n-th signing key of the node operator #`_operator_id` * @param _operator_id Node Operator id * @param _index Index of the key, starting with 0 * @return key Key * @return depositSignature Signature needed for a deposit_contract.deposit call * @return used Flag indication if the key was used in the staking */ function getSigningKey(uint256 _operator_id, uint256 _index) external view returns (bytes key, bytes depositSignature, bool used); event SigningKeyAdded(uint256 indexed operatorId, bytes pubkey); event SigningKeyRemoved(uint256 indexed operatorId, bytes pubkey); } // Part: OpenZeppelin/[email protected]/IERC20 /** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 */ interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address who) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function transfer(address to, uint256 value) external returns (bool); function approve(address spender, uint256 value) external returns (bool); function transferFrom(address from, address to, uint256 value) external returns (bool); event Transfer( address indexed from, address indexed to, uint256 value ); event Approval( address indexed owner, address indexed spender, uint256 value ); } // Part: aragon/[email protected]/IsContract contract IsContract { /* * NOTE: this should NEVER be used for authentication * (see pitfalls: https://github.com/fergarrui/ethereum-security/tree/master/contracts/extcodesize). * * This is only intended to be used as a sanity check that an address is actually a contract, * RATHER THAN an address not being a contract. */ function isContract(address _target) internal view returns (bool) { if (_target == address(0)) { return false; } uint256 size; assembly { size := extcodesize(_target) } return size > 0; } } // Part: aragon/[email protected]/SafeMath /** * @title SafeMath * @dev Math operations with safety checks that revert on error */ library SafeMath { string private constant ERROR_ADD_OVERFLOW = "MATH_ADD_OVERFLOW"; string private constant ERROR_SUB_UNDERFLOW = "MATH_SUB_UNDERFLOW"; string private constant ERROR_MUL_OVERFLOW = "MATH_MUL_OVERFLOW"; string private constant ERROR_DIV_ZERO = "MATH_DIV_ZERO"; /** * @dev Multiplies two numbers, reverts on overflow. */ function mul(uint256 _a, uint256 _b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (_a == 0) { return 0; } uint256 c = _a * _b; require(c / _a == _b, ERROR_MUL_OVERFLOW); return c; } /** * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. */ function div(uint256 _a, uint256 _b) internal pure returns (uint256) { require(_b > 0, ERROR_DIV_ZERO); // Solidity only automatically asserts when dividing by 0 uint256 c = _a / _b; // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 _a, uint256 _b) internal pure returns (uint256) { require(_b <= _a, ERROR_SUB_UNDERFLOW); uint256 c = _a - _b; return c; } /** * @dev Adds two numbers, reverts on overflow. */ function add(uint256 _a, uint256 _b) internal pure returns (uint256) { uint256 c = _a + _b; require(c >= _a, ERROR_ADD_OVERFLOW); return c; } /** * @dev Divides two numbers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, ERROR_DIV_ZERO); return a % b; } } // Part: aragon/[email protected]/SafeMath64 /** * @title SafeMath64 * @dev Math operations for uint64 with safety checks that revert on error */ library SafeMath64 { string private constant ERROR_ADD_OVERFLOW = "MATH64_ADD_OVERFLOW"; string private constant ERROR_SUB_UNDERFLOW = "MATH64_SUB_UNDERFLOW"; string private constant ERROR_MUL_OVERFLOW = "MATH64_MUL_OVERFLOW"; string private constant ERROR_DIV_ZERO = "MATH64_DIV_ZERO"; /** * @dev Multiplies two numbers, reverts on overflow. */ function mul(uint64 _a, uint64 _b) internal pure returns (uint64) { uint256 c = uint256(_a) * uint256(_b); require(c < 0x010000000000000000, ERROR_MUL_OVERFLOW); // 2**64 (less gas this way) return uint64(c); } /** * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. */ function div(uint64 _a, uint64 _b) internal pure returns (uint64) { require(_b > 0, ERROR_DIV_ZERO); // Solidity only automatically asserts when dividing by 0 uint64 c = _a / _b; // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint64 _a, uint64 _b) internal pure returns (uint64) { require(_b <= _a, ERROR_SUB_UNDERFLOW); uint64 c = _a - _b; return c; } /** * @dev Adds two numbers, reverts on overflow. */ function add(uint64 _a, uint64 _b) internal pure returns (uint64) { uint64 c = _a + _b; require(c >= _a, ERROR_ADD_OVERFLOW); return c; } /** * @dev Divides two numbers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint64 a, uint64 b) internal pure returns (uint64) { require(b != 0, ERROR_DIV_ZERO); return a % b; } } // Part: aragon/[email protected]/UnstructuredStorage library UnstructuredStorage { function getStorageBool(bytes32 position) internal view returns (bool data) { assembly { data := sload(position) } } function getStorageAddress(bytes32 position) internal view returns (address data) { assembly { data := sload(position) } } function getStorageBytes32(bytes32 position) internal view returns (bytes32 data) { assembly { data := sload(position) } } function getStorageUint256(bytes32 position) internal view returns (uint256 data) { assembly { data := sload(position) } } function setStorageBool(bytes32 position, bool data) internal { assembly { sstore(position, data) } } function setStorageAddress(bytes32 position, address data) internal { assembly { sstore(position, data) } } function setStorageBytes32(bytes32 position, bytes32 data) internal { assembly { sstore(position, data) } } function setStorageUint256(bytes32 position, uint256 data) internal { assembly { sstore(position, data) } } } // Part: ILido /** * @title Liquid staking pool * * For the high-level description of the pool operation please refer to the paper. * Pool manages withdrawal keys and fees. It receives ether submitted by users on the ETH 1 side * and stakes it via the deposit_contract.sol contract. It doesn't hold ether on it's balance, * only a small portion (buffer) of it. * It also mints new tokens for rewards generated at the ETH 2.0 side. */ interface ILido { /** * @dev From ISTETH interface, because "Interfaces cannot inherit". */ function totalSupply() external view returns (uint256); function getTotalShares() external view returns (uint256); /** * @notice Stop pool routine operations */ function stop() external; /** * @notice Resume pool routine operations */ function resume() external; event Stopped(); event Resumed(); /** * @notice Set fee rate to `_feeBasisPoints` basis points. The fees are accrued when oracles report staking results * @param _feeBasisPoints Fee rate, in basis points */ function setFee(uint16 _feeBasisPoints) external; /** * @notice Set fee distribution: `_treasuryFeeBasisPoints` basis points go to the treasury, `_insuranceFeeBasisPoints` basis points go to the insurance fund, `_operatorsFeeBasisPoints` basis points go to node operators. The sum has to be 10 000. */ function setFeeDistribution( uint16 _treasuryFeeBasisPoints, uint16 _insuranceFeeBasisPoints, uint16 _operatorsFeeBasisPoints) external; /** * @notice Returns staking rewards fee rate */ function getFee() external view returns (uint16 feeBasisPoints); /** * @notice Returns fee distribution proportion */ function getFeeDistribution() external view returns (uint16 treasuryFeeBasisPoints, uint16 insuranceFeeBasisPoints, uint16 operatorsFeeBasisPoints); event FeeSet(uint16 feeBasisPoints); event FeeDistributionSet(uint16 treasuryFeeBasisPoints, uint16 insuranceFeeBasisPoints, uint16 operatorsFeeBasisPoints); /** * @notice Set credentials to withdraw ETH on ETH 2.0 side after the phase 2 is launched to `_withdrawalCredentials` * @dev Note that setWithdrawalCredentials discards all unused signing keys as the signatures are invalidated. * @param _withdrawalCredentials hash of withdrawal multisignature key as accepted by * the deposit_contract.deposit function */ function setWithdrawalCredentials(bytes32 _withdrawalCredentials) external; /** * @notice Returns current credentials to withdraw ETH on ETH 2.0 side after the phase 2 is launched */ function getWithdrawalCredentials() external view returns (bytes); event WithdrawalCredentialsSet(bytes32 withdrawalCredentials); /** * @notice Ether on the ETH 2.0 side reported by the oracle * @param _epoch Epoch id * @param _eth2balance Balance in wei on the ETH 2.0 side */ function pushBeacon(uint256 _epoch, uint256 _eth2balance) external; // User functions /** * @notice Adds eth to the pool * @return StETH Amount of StETH generated */ function submit(address _referral) external payable returns (uint256 StETH); // Records a deposit made by a user event Submitted(address indexed sender, uint256 amount, address referral); // The `_amount` of ether was sent to the deposit_contract.deposit function. event Unbuffered(uint256 amount); /** * @notice Issues withdrawal request. Large withdrawals will be processed only after the phase 2 launch. * @param _amount Amount of StETH to burn * @param _pubkeyHash Receiving address */ function withdraw(uint256 _amount, bytes32 _pubkeyHash) external; // Requested withdrawal of `etherAmount` to `pubkeyHash` on the ETH 2.0 side, `tokenAmount` burned by `sender`, // `sentFromBuffer` was sent on the current Ethereum side. event Withdrawal(address indexed sender, uint256 tokenAmount, uint256 sentFromBuffer, bytes32 indexed pubkeyHash, uint256 etherAmount); // Info functions /** * @notice Gets the amount of Ether controlled by the system */ function getTotalPooledEther() external view returns (uint256); /** * @notice Gets the amount of Ether temporary buffered on this contract balance */ function getBufferedEther() external view returns (uint256); /** * @notice Returns the key values related to Beacon-side * @return depositedValidators - number of deposited validators * @return beaconValidators - number of Lido's validators visible in the Beacon state, reported by oracles * @return beaconBalance - total amount of Beacon-side Ether (sum of all the balances of Lido validators) */ function getBeaconStat() external view returns (uint256 depositedValidators, uint256 beaconValidators, uint256 beaconBalance); } // Part: Pausable contract Pausable { using UnstructuredStorage for bytes32; event Stopped(); event Resumed(); bytes32 internal constant ACTIVE_FLAG_POSITION = keccak256("lido.Pausable.activeFlag"); modifier whenNotStopped() { require(ACTIVE_FLAG_POSITION.getStorageBool(), "CONTRACT_IS_STOPPED"); _; } modifier whenStopped() { require(!ACTIVE_FLAG_POSITION.getStorageBool(), "CONTRACT_IS_ACTIVE"); _; } function isStopped() external view returns (bool) { return !ACTIVE_FLAG_POSITION.getStorageBool(); } function _stop() internal whenNotStopped { ACTIVE_FLAG_POSITION.setStorageBool(false); emit Stopped(); } function _resume() internal whenStopped { ACTIVE_FLAG_POSITION.setStorageBool(true); emit Resumed(); } } // Part: StETH /** * @title Interest-bearing ERC20-like token for Lido Liquid Stacking protocol. * * This contract is abstract. To make the contract deployable override the * `_getTotalPooledEther` function. `Lido.sol` contract inherits StETH and defines * the `_getTotalPooledEther` function. * * StETH balances are dynamic and represent the holder's share in the total amount * of Ether controlled by the protocol. Account shares aren't normalized, so the * contract also stores the sum of all shares to calculate each account's token balance * which equals to: * * shares[account] * _getTotalPooledEther() / _getTotalShares() * * For example, assume that we have: * * _getTotalPooledEther() -> 10 ETH * sharesOf(user1) -> 100 * sharesOf(user2) -> 400 * * Therefore: * * balanceOf(user1) -> 2 tokens which corresponds 2 ETH * balanceOf(user2) -> 8 tokens which corresponds 8 ETH * * Since balances of all token holders change when the amount of total pooled Ether * changes, this token cannot fully implement ERC20 standard: it only emits `Transfer` * events upon explicit transfer between holders. In contrast, when total amount of * pooled Ether increases, no `Transfer` events are generated: doing so would require * emitting an event for each token holder and thus running an unbounded loop. * * The token inherits from `Pausable` and uses `whenNotStopped` modifier for methods * which change `shares` or `allowances`. `_stop` and `_resume` functions are overriden * in `Lido.sol` and might be called by an account with the `PAUSE_ROLE` assigned by the * DAO. This is useful for emergency scenarios, e.g. a protocol bug, where one might want * to freeze all token transfers and approvals until the emergency is resolved. */ contract StETH is IERC20, Pausable { using SafeMath for uint256; using UnstructuredStorage for bytes32; /** * @dev StETH balances are dynamic and are calculated based on the accounts' shares * and the total amount of Ether controlled by the protocol. Account shares aren't * normalized, so the contract also stores the sum of all shares to calculate * each account's token balance which equals to: * * shares[account] * _getTotalPooledEther() / _getTotalShares() */ mapping (address => uint256) private shares; /** * @dev Allowances are nominated in tokens, not token shares. */ mapping (address => mapping (address => uint256)) private allowances; /** * @dev Storage position used for holding the total amount of shares in existence. * * The Lido protocol is built on top of Aragon and uses the Unstructured Storage pattern * for value types: * * https://blog.openzeppelin.com/upgradeability-using-unstructured-storage * https://blog.8bitzen.com/posts/20-02-2020-understanding-how-solidity-upgradeable-unstructured-proxies-work * * For reference types, conventional storage variables are used since it's non-trivial * and error-prone to implement reference-type unstructured storage using Solidity v0.4; * see https://github.com/lidofinance/lido-dao/issues/181#issuecomment-736098834 */ bytes32 internal constant TOTAL_SHARES_POSITION = keccak256("lido.StETH.totalShares"); /** * @return the name of the token. */ function name() public pure returns (string) { return "Liquid staked Ether 2.0"; } /** * @return the symbol of the token, usually a shorter version of the * name. */ function symbol() public pure returns (string) { return "stETH"; } /** * @return the number of decimals for getting user representation of a token amount. */ function decimals() public pure returns (uint8) { return 18; } /** * @return the amount of tokens in existence. * * @dev Always equals to `_getTotalPooledEther()` since token amount * is pegged to the total amount of Ether controlled by the protocol. */ function totalSupply() public view returns (uint256) { return _getTotalPooledEther(); } /** * @return the entire amount of Ether controlled by the protocol. * * @dev The sum of all ETH balances in the protocol, equals to the total supply of stETH. */ function getTotalPooledEther() public view returns (uint256) { return _getTotalPooledEther(); } /** * @return the amount of tokens owned by the `_account`. * * @dev Balances are dynamic and equal the `_account`'s share in the amount of the * total Ether controlled by the protocol. See `sharesOf`. */ function balanceOf(address _account) public view returns (uint256) { return getPooledEthByShares(_sharesOf(_account)); } /** * @notice Moves `_amount` tokens from the caller's account to the `_recipient` account. * * @return a boolean value indicating whether the operation succeeded. * Emits a `Transfer` event. * * Requirements: * * - `_recipient` cannot be the zero address. * - the caller must have a balance of at least `_amount`. * - the contract must not be paused. * * @dev The `_amount` argument is the amount of tokens, not shares. */ function transfer(address _recipient, uint256 _amount) public returns (bool) { _transfer(msg.sender, _recipient, _amount); return true; } /** * @return the remaining number of tokens that `_spender` is allowed to spend * on behalf of `_owner` through `transferFrom`. This is zero by default. * * @dev This value changes when `approve` or `transferFrom` is called. */ function allowance(address _owner, address _spender) public view returns (uint256) { return allowances[_owner][_spender]; } /** * @notice Sets `_amount` as the allowance of `_spender` over the caller's tokens. * * @return a boolean value indicating whether the operation succeeded. * Emits an `Approval` event. * * Requirements: * * - `_spender` cannot be the zero address. * - the contract must not be paused. * * @dev The `_amount` argument is the amount of tokens, not shares. */ function approve(address _spender, uint256 _amount) public returns (bool) { _approve(msg.sender, _spender, _amount); return true; } /** * @notice Moves `_amount` tokens from `_sender` to `_recipient` using the * allowance mechanism. `_amount` is then deducted from the caller's * allowance. * * @return a boolean value indicating whether the operation succeeded. * * Emits a `Transfer` event. * Emits an `Approval` event indicating the updated allowance. * * Requirements: * * - `_sender` and `_recipient` cannot be the zero addresses. * - `_sender` must have a balance of at least `_amount`. * - the caller must have allowance for `_sender`'s tokens of at least `_amount`. * - the contract must not be paused. * * @dev The `_amount` argument is the amount of tokens, not shares. */ function transferFrom(address _sender, address _recipient, uint256 _amount) public returns (bool) { uint256 currentAllowance = allowances[_sender][msg.sender]; require(currentAllowance >= _amount, "TRANSFER_AMOUNT_EXCEEDS_ALLOWANCE"); _transfer(_sender, _recipient, _amount); _approve(_sender, msg.sender, currentAllowance.sub(_amount)); return true; } /** * @notice Atomically increases the allowance granted to `_spender` by the caller by `_addedValue`. * * This is an alternative to `approve` that can be used as a mitigation for * problems described in: * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol#L42 * Emits an `Approval` event indicating the updated allowance. * * Requirements: * * - `_spender` cannot be the the zero address. * - the contract must not be paused. */ function increaseAllowance(address _spender, uint256 _addedValue) public returns (bool) { _approve(msg.sender, _spender, allowances[msg.sender][_spender].add(_addedValue)); return true; } /** * @notice Atomically decreases the allowance granted to `_spender` by the caller by `_subtractedValue`. * * This is an alternative to `approve` that can be used as a mitigation for * problems described in: * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol#L42 * Emits an `Approval` event indicating the updated allowance. * * Requirements: * * - `_spender` cannot be the zero address. * - `_spender` must have allowance for the caller of at least `_subtractedValue`. * - the contract must not be paused. */ function decreaseAllowance(address _spender, uint256 _subtractedValue) public returns (bool) { uint256 currentAllowance = allowances[msg.sender][_spender]; require(currentAllowance >= _subtractedValue, "DECREASED_ALLOWANCE_BELOW_ZERO"); _approve(msg.sender, _spender, currentAllowance.sub(_subtractedValue)); return true; } /** * @return the total amount of shares in existence. * * @dev The sum of all accounts' shares can be an arbitrary number, therefore * it is necessary to store it in order to calculate each account's relative share. */ function getTotalShares() public view returns (uint256) { return _getTotalShares(); } /** * @return the amount of shares owned by `_account`. */ function sharesOf(address _account) public view returns (uint256) { return _sharesOf(_account); } /** * @return the amount of shares that corresponds to `_ethAmount` protocol-controlled Ether. */ function getSharesByPooledEth(uint256 _ethAmount) public view returns (uint256) { uint256 totalPooledEther = _getTotalPooledEther(); if (totalPooledEther == 0) { return 0; } else { return _ethAmount .mul(_getTotalShares()) .div(totalPooledEther); } } /** * @return the amount of Ether that corresponds to `_sharesAmount` token shares. */ function getPooledEthByShares(uint256 _sharesAmount) public view returns (uint256) { uint256 totalShares = _getTotalShares(); if (totalShares == 0) { return 0; } else { return _sharesAmount .mul(_getTotalPooledEther()) .div(totalShares); } } /** * @return the total amount (in wei) of Ether controlled by the protocol. * @dev This is used for calaulating tokens from shares and vice versa. * @dev This function is required to be implemented in a derived contract. */ function _getTotalPooledEther() internal view returns (uint256); /** * @notice Moves `_amount` tokens from `_sender` to `_recipient`. * Emits a `Transfer` event. */ function _transfer(address _sender, address _recipient, uint256 _amount) internal { uint256 _sharesToTransfer = getSharesByPooledEth(_amount); _transferShares(_sender, _recipient, _sharesToTransfer); emit Transfer(_sender, _recipient, _amount); } /** * @notice Sets `_amount` as the allowance of `_spender` over the `_owner` s tokens. * * Emits an `Approval` event. * * Requirements: * * - `_owner` cannot be the zero address. * - `_spender` cannot be the zero address. * - the contract must not be paused. */ function _approve(address _owner, address _spender, uint256 _amount) internal whenNotStopped { require(_owner != address(0), "APPROVE_FROM_ZERO_ADDRESS"); require(_spender != address(0), "APPROVE_TO_ZERO_ADDRESS"); allowances[_owner][_spender] = _amount; emit Approval(_owner, _spender, _amount); } /** * @return the total amount of shares in existence. */ function _getTotalShares() internal view returns (uint256) { return TOTAL_SHARES_POSITION.getStorageUint256(); } /** * @return the amount of shares owned by `_account`. */ function _sharesOf(address _account) internal view returns (uint256) { return shares[_account]; } /** * @notice Moves `_sharesAmount` shares from `_sender` to `_recipient`. * * Requirements: * * - `_sender` cannot be the zero address. * - `_recipient` cannot be the zero address. * - `_sender` must hold at least `_sharesAmount` shares. * - the contract must not be paused. */ function _transferShares(address _sender, address _recipient, uint256 _sharesAmount) internal whenNotStopped { require(_sender != address(0), "TRANSFER_FROM_THE_ZERO_ADDRESS"); require(_recipient != address(0), "TRANSFER_TO_THE_ZERO_ADDRESS"); uint256 currentSenderShares = shares[_sender]; require(_sharesAmount <= currentSenderShares, "TRANSFER_AMOUNT_EXCEEDS_BALANCE"); shares[_sender] = currentSenderShares.sub(_sharesAmount); shares[_recipient] = shares[_recipient].add(_sharesAmount); } /** * @notice Creates `_sharesAmount` shares and assigns them to `_recipient`, increasing the total amount of shares. * @dev This doesn't increase the token total supply. * * Requirements: * * - `_recipient` cannot be the zero address. * - the contract must not be paused. */ function _mintShares(address _recipient, uint256 _sharesAmount) internal whenNotStopped returns (uint256 newTotalShares) { require(_recipient != address(0), "MINT_TO_THE_ZERO_ADDRESS"); newTotalShares = _getTotalShares().add(_sharesAmount); TOTAL_SHARES_POSITION.setStorageUint256(newTotalShares); shares[_recipient] = shares[_recipient].add(_sharesAmount); // Notice: we're not emitting a Transfer event from the zero address here since shares mint // works by taking the amount of tokens corresponding to the minted shares from all other // token holders, proportionally to their share. The total supply of the token doesn't change // as the result. This is equivalent to performing a send from each other token holder's // address to `address`, but we cannot reflect this as it would require sending an unbounded // number of events. } /** * @notice Destroys `_sharesAmount` shares from `_account`'s holdings, decreasing the total amount of shares. * @dev This doesn't decrease the token total supply. * * Requirements: * * - `_account` cannot be the zero address. * - `_account` must hold at least `_sharesAmount` shares. * - the contract must not be paused. */ function _burnShares(address _account, uint256 _sharesAmount) internal whenNotStopped returns (uint256 newTotalShares) { require(_account != address(0), "BURN_FROM_THE_ZERO_ADDRESS"); uint256 accountShares = shares[_account]; require(_sharesAmount <= accountShares, "BURN_AMOUNT_EXCEEDS_BALANCE"); newTotalShares = _getTotalShares().sub(_sharesAmount); TOTAL_SHARES_POSITION.setStorageUint256(newTotalShares); shares[_account] = accountShares.sub(_sharesAmount); // Notice: we're not emitting a Transfer event to the zero address here since shares burn // works by redistributing the amount of tokens corresponding to the burned shares between // all other token holders. The total supply of the token doesn't change as the result. // This is equivalent to performing a send from `address` to each other token holder address, // but we cannot reflect this as it would require sending an unbounded number of events. } } // File: Lido.sol /** * @title Liquid staking pool implementation * * Lido is an Ethereum 2.0 liquid staking protocol solving the problem of frozen staked Ethers * until transfers become available in Ethereum 2.0. * Whitepaper: https://lido.fi/static/Lido:Ethereum-Liquid-Staking.pdf * * NOTE: the code below assumes moderate amount of node operators, e.g. up to 50. * * Since balances of all token holders change when the amount of total pooled Ether * changes, this token cannot fully implement ERC20 standard: it only emits `Transfer` * events upon explicit transfer between holders. In contrast, when Lido oracle reports * rewards, no Transfer events are generated: doing so would require emitting an event * for each token holder and thus running an unbounded loop. */ contract Lido is ILido, IsContract, StETH { using SafeMath for uint256; using SafeMath64 for uint64; using UnstructuredStorage for bytes32; uint256 constant public PUBKEY_LENGTH = 48; uint256 constant public WITHDRAWAL_CREDENTIALS_LENGTH = 32; uint256 constant public SIGNATURE_LENGTH = 96; uint256 constant public DEPOSIT_SIZE = 32 ether; uint256 internal constant DEPOSIT_AMOUNT_UNIT = 1000000000 wei; /// @dev default value for maximum number of Ethereum 2.0 validators registered in a single depositBufferedEther call uint256 internal constant DEFAULT_MAX_DEPOSITS_PER_CALL = 16; bytes32 internal constant FEE_POSITION = keccak256("lido.Lido.fee"); bytes32 internal constant TREASURY_FEE_POSITION = keccak256("lido.Lido.treasuryFee"); bytes32 internal constant INSURANCE_FEE_POSITION = keccak256("lido.Lido.insuranceFee"); bytes32 internal constant NODE_OPERATORS_FEE_POSITION = keccak256("lido.Lido.nodeOperatorsFee"); bytes32 internal constant DEPOSIT_CONTRACT_POSITION = keccak256("lido.Lido.depositContract"); bytes32 internal constant ORACLE_POSITION = keccak256("lido.Lido.oracle"); bytes32 internal constant NODE_OPERATORS_REGISTRY_POSITION = keccak256("lido.Lido.nodeOperatorsRegistry"); bytes32 internal constant TREASURY_POSITION = keccak256("lido.Lido.treasury"); bytes32 internal constant INSURANCE_FUND_POSITION = keccak256("lido.Lido.insuranceFund"); /// @dev amount of Ether (on the current Ethereum side) buffered on this smart contract balance bytes32 internal constant BUFFERED_ETHER_POSITION = keccak256("lido.Lido.bufferedEther"); /// @dev number of deposited validators (incrementing counter of deposit operations). bytes32 internal constant DEPOSITED_VALIDATORS_POSITION = keccak256("lido.Lido.depositedValidators"); /// @dev total amount of Beacon-side Ether (sum of all the balances of Lido validators) bytes32 internal constant BEACON_BALANCE_POSITION = keccak256("lido.Lido.beaconBalance"); /// @dev number of Lido's validators available in the Beacon state bytes32 internal constant BEACON_VALIDATORS_POSITION = keccak256("lido.Lido.beaconValidators"); /// @dev Credentials which allows the DAO to withdraw Ether on the 2.0 side bytes32 internal constant WITHDRAWAL_CREDENTIALS_POSITION = keccak256("lido.Lido.withdrawalCredentials"); address public admin = msg.sender; /** * @dev Lido contract must be initialized with following variables: * @param depositContract official ETH2 Deposit contract * @param _oracle oracle contract * @param _operators instance of Node Operators Registry * @param _treasury Treasury address * @param _insuranceFund Insurance fund address */ constructor( IDepositContract depositContract, address _oracle, INodeOperatorsRegistry _operators, address _treasury, address _insuranceFund ) public { _setDepositContract(depositContract); _setOracle(_oracle); _setOperators(_operators); _setTreasury(_treasury); _setInsuranceFund(_insuranceFund); } /** * @notice Send funds to the pool * @dev Users are able to submit their funds by transacting to the fallback function. * Unlike vanilla Eth2.0 Deposit contract, accepting only 32-Ether transactions, Lido * accepts payments of any size. Submitted Ethers are stored in Buffer until someone calls * depositBufferedEther() and pushes them to the ETH2 Deposit contract. */ function() external payable { // protection against accidental submissions by calling non-existent function require(msg.data.length == 0, "NON_EMPTY_DATA"); _submit(0); } /** * @notice Send funds to the pool with optional _referral parameter * @dev This function is alternative way to submit funds. Supports optional referral address. * @return Amount of StETH shares generated */ function submit(address _referral) external payable returns (uint256) { return _submit(_referral); } /** * @notice Deposits buffered ethers to the official DepositContract. * @dev This function is separated from submit() to reduce the cost of sending funds. */ function depositBufferedEther() external { return _depositBufferedEther(DEFAULT_MAX_DEPOSITS_PER_CALL); } /** * @notice Deposits buffered ethers to the official DepositContract, making no more than `_maxDeposits` deposit calls. * @dev This function is separated from submit() to reduce the cost of sending funds. */ function depositBufferedEther(uint256 _maxDeposits) external { return _depositBufferedEther(_maxDeposits); } /** * @notice Stop pool routine operations */ function stop() external { _stop(); } /** * @notice Resume pool routine operations */ function resume() external { _resume(); } /** * @notice Set fee rate to `_feeBasisPoints` basis points. The fees are accrued when oracles report staking results * @param _feeBasisPoints Fee rate, in basis points */ function setFee(uint16 _feeBasisPoints) external { require(msg.sender == admin, "UNAUTHORIZED"); _setBPValue(FEE_POSITION, _feeBasisPoints); emit FeeSet(_feeBasisPoints); } /** * @notice Set fee distribution: `_treasuryFeeBasisPoints` basis points go to the treasury, `_insuranceFeeBasisPoints` basis points go to the insurance fund, `_operatorsFeeBasisPoints` basis points go to node operators. The sum has to be 10 000. */ function setFeeDistribution( uint16 _treasuryFeeBasisPoints, uint16 _insuranceFeeBasisPoints, uint16 _operatorsFeeBasisPoints ) external { require(msg.sender == admin, "UNAUTHORIZED"); require( 10000 == uint256(_treasuryFeeBasisPoints) .add(uint256(_insuranceFeeBasisPoints)) .add(uint256(_operatorsFeeBasisPoints)), "FEES_DONT_ADD_UP" ); _setBPValue(TREASURY_FEE_POSITION, _treasuryFeeBasisPoints); _setBPValue(INSURANCE_FEE_POSITION, _insuranceFeeBasisPoints); _setBPValue(NODE_OPERATORS_FEE_POSITION, _operatorsFeeBasisPoints); emit FeeDistributionSet(_treasuryFeeBasisPoints, _insuranceFeeBasisPoints, _operatorsFeeBasisPoints); } /** * @notice Set authorized oracle contract address to `_oracle` * @dev Contract specified here is allowed to make periodical updates of beacon states * by calling pushBeacon. * @param _oracle oracle contract */ function setOracle(address _oracle) external { require(msg.sender == admin, "UNAUTHORIZED"); _setOracle(_oracle); } /** * @notice Set treasury contract address to `_treasury` * @dev Contract specified here is used to accumulate the protocol treasury fee. * @param _treasury contract which accumulates treasury fee. */ function setTreasury(address _treasury) external { require(msg.sender == admin, "UNAUTHORIZED"); _setTreasury(_treasury); } /** * @notice Set insuranceFund contract address to `_insuranceFund` * @dev Contract specified here is used to accumulate the protocol insurance fee. * @param _insuranceFund contract which accumulates insurance fee. */ function setInsuranceFund(address _insuranceFund) external { require(msg.sender == admin, "UNAUTHORIZED"); _setInsuranceFund(_insuranceFund); } /** * @notice Set credentials to withdraw ETH on ETH 2.0 side after the phase 2 is launched to `_withdrawalCredentials` * @dev Note that setWithdrawalCredentials discards all unused signing keys as the signatures are invalidated. * @param _withdrawalCredentials hash of withdrawal multisignature key as accepted by * the deposit_contract.deposit function */ function setWithdrawalCredentials(bytes32 _withdrawalCredentials) external { require(msg.sender == admin, "UNAUTHORIZED"); WITHDRAWAL_CREDENTIALS_POSITION.setStorageBytes32(_withdrawalCredentials); getOperators().trimUnusedKeys(); emit WithdrawalCredentialsSet(_withdrawalCredentials); } /** * @notice Issues withdrawal request. Not implemented. * @param _amount Amount of StETH to withdraw * @param _pubkeyHash Receiving address */ function withdraw(uint256 _amount, bytes32 _pubkeyHash) external whenNotStopped { /* solhint-disable-line no-unused-vars */ //will be upgraded to an actual implementation when withdrawals are enabled (Phase 1.5 or 2 of Eth2 launch, likely late 2021 or 2022). //at the moment withdrawals are not possible in the beacon chain and there's no workaround revert("NOT_IMPLEMENTED_YET"); } function simulateBeaconRewards() public { simulateBeaconRewards(1010000000000000000); } function simulateBeaconRewards(uint256 _totalSupplyMult) public { uint256 totalSupply = _getTotalPooledEther(); uint256 newTotalSupply = (totalSupply * _totalSupplyMult) / 10**18; uint256 beaconValidators = BEACON_VALIDATORS_POSITION.getStorageUint256(); uint256 beaconBalance = BEACON_BALANCE_POSITION.getStorageUint256(); beaconBalance = beaconBalance.add(newTotalSupply).sub(totalSupply); pushBeacon(beaconValidators, beaconBalance); } /** * @notice Updates the number of Lido-controlled keys in the beacon validators set and their total balance. * @dev periodically called by the Oracle contract * @param _beaconValidators number of Lido's keys in the beacon state * @param _beaconBalance simmarized balance of Lido-controlled keys in wei */ function pushBeacon(uint256 _beaconValidators, uint256 _beaconBalance) public whenNotStopped { require(msg.sender == getOracle(), "APP_AUTH_FAILED"); uint256 depositedValidators = DEPOSITED_VALIDATORS_POSITION.getStorageUint256(); require(_beaconValidators <= depositedValidators, "REPORTED_MORE_DEPOSITED"); uint256 beaconValidators = BEACON_VALIDATORS_POSITION.getStorageUint256(); // Since the calculation of funds in the ingress queue is based on the number of validators // that are in a transient state (deposited but not seen on beacon yet), we can't decrease the previously // reported number (we'll be unable to figure out who is in the queue and count them). // See LIP-1 for details https://github.com/lidofinance/lido-improvement-proposals/blob/develop/LIPS/lip-1.md require(_beaconValidators >= beaconValidators, "REPORTED_LESS_VALIDATORS"); uint256 appearedValidators = _beaconValidators.sub(beaconValidators); // RewardBase is the amount of money that is not included in the reward calculation // Just appeared validators * 32 added to the previously reported beacon balance uint256 rewardBase = (appearedValidators.mul(DEPOSIT_SIZE)).add(BEACON_BALANCE_POSITION.getStorageUint256()); // Save the current beacon balance and validators to // calcuate rewards on the next push BEACON_BALANCE_POSITION.setStorageUint256(_beaconBalance); BEACON_VALIDATORS_POSITION.setStorageUint256(_beaconValidators); if (_beaconBalance > rewardBase) { uint256 rewards = _beaconBalance.sub(rewardBase); distributeRewards(rewards); } } /** * @notice Returns staking rewards fee rate */ function getFee() external view returns (uint16 feeBasisPoints) { return _getFee(); } /** * @notice Returns fee distribution proportion */ function getFeeDistribution() external view returns ( uint16 treasuryFeeBasisPoints, uint16 insuranceFeeBasisPoints, uint16 operatorsFeeBasisPoints ) { return _getFeeDistribution(); } /** * @notice Returns current credentials to withdraw ETH on ETH 2.0 side after the phase 2 is launched */ function getWithdrawalCredentials() public view returns (bytes32) { return WITHDRAWAL_CREDENTIALS_POSITION.getStorageBytes32(); } /** * @notice Get the amount of Ether temporary buffered on this contract balance * @dev Buffered balance is kept on the contract from the moment the funds are received from user * until the moment they are actually sent to the official Deposit contract. * @return uint256 of buffered funds in wei */ function getBufferedEther() external view returns (uint256) { return _getBufferedEther(); } /** * @notice Gets deposit contract handle */ function getDepositContract() public view returns (IDepositContract) { return IDepositContract(DEPOSIT_CONTRACT_POSITION.getStorageAddress()); } /** * @notice Gets authorized oracle address * @return address of oracle contract */ function getOracle() public view returns (address) { return ORACLE_POSITION.getStorageAddress(); } /** * @notice Gets node operators registry interface handle */ function getOperators() public view returns (INodeOperatorsRegistry) { return INodeOperatorsRegistry(NODE_OPERATORS_REGISTRY_POSITION.getStorageAddress()); } /** * @notice Returns the treasury address */ function getTreasury() public view returns (address) { return TREASURY_POSITION.getStorageAddress(); } /** * @notice Returns the insurance fund address */ function getInsuranceFund() public view returns (address) { return INSURANCE_FUND_POSITION.getStorageAddress(); } /** * @notice Returns the key values related to Beacon-side * @return depositedValidators - number of deposited validators * @return beaconValidators - number of Lido's validators visible in the Beacon state, reported by oracles * @return beaconBalance - total amount of Beacon-side Ether (sum of all the balances of Lido validators) */ function getBeaconStat() public view returns (uint256 depositedValidators, uint256 beaconValidators, uint256 beaconBalance) { depositedValidators = DEPOSITED_VALIDATORS_POSITION.getStorageUint256(); beaconValidators = BEACON_VALIDATORS_POSITION.getStorageUint256(); beaconBalance = BEACON_BALANCE_POSITION.getStorageUint256(); } /** * @dev Sets the address of Deposit contract * @param _contract the address of Deposit contract */ function _setDepositContract(IDepositContract _contract) internal { require(isContract(address(_contract)), "NOT_A_CONTRACT"); DEPOSIT_CONTRACT_POSITION.setStorageAddress(address(_contract)); } /** * @dev Internal function to set authorized oracle address * @param _oracle oracle contract */ function _setOracle(address _oracle) internal { ORACLE_POSITION.setStorageAddress(_oracle); } /** * @dev Internal function to set node operator registry address * @param _r registry of node operators */ function _setOperators(INodeOperatorsRegistry _r) internal { require(isContract(_r), "NOT_A_CONTRACT"); NODE_OPERATORS_REGISTRY_POSITION.setStorageAddress(_r); } function _setTreasury(address _treasury) internal { require(_treasury != address(0), "SET_TREASURY_ZERO_ADDRESS"); TREASURY_POSITION.setStorageAddress(_treasury); } function _setInsuranceFund(address _insuranceFund) internal { require(_insuranceFund != address(0), "SET_INSURANCE_FUND_ZERO_ADDRESS"); INSURANCE_FUND_POSITION.setStorageAddress(_insuranceFund); } /** * @dev Process user deposit, mints liquid tokens and increase the pool buffer * @param _referral address of referral. * @return amount of StETH shares generated */ function _submit(address _referral) internal whenNotStopped returns (uint256) { address sender = msg.sender; uint256 deposit = msg.value; require(deposit != 0, "ZERO_DEPOSIT"); uint256 sharesAmount = getSharesByPooledEth(deposit); if (sharesAmount == 0) { // totalControlledEther is 0: either the first-ever deposit or complete slashing // assume that shares correspond to Ether 1-to-1 sharesAmount = deposit; } _mintShares(sender, sharesAmount); _submitted(sender, deposit, _referral); _emitTransferAfterMintingShares(sender, sharesAmount); return sharesAmount; } /** * @dev Emits an {Transfer} event where from is 0 address. Indicates mint events. */ function _emitTransferAfterMintingShares(address _to, uint256 _sharesAmount) internal { emit Transfer(address(0), _to, getPooledEthByShares(_sharesAmount)); } /** * @dev Deposits buffered eth to the DepositContract and assigns chunked deposits to node operators */ function _depositBufferedEther(uint256 _maxDeposits) internal whenNotStopped { uint256 buffered = _getBufferedEther(); if (buffered >= DEPOSIT_SIZE) { uint256 unaccounted = _getUnaccountedEther(); uint256 numDeposits = buffered.div(DEPOSIT_SIZE); _markAsUnbuffered(_ETH2Deposit(numDeposits < _maxDeposits ? numDeposits : _maxDeposits)); assert(_getUnaccountedEther() == unaccounted); } } /** * @dev Performs deposits to the ETH 2.0 side * @param _numDeposits Number of deposits to perform * @return actually deposited Ether amount */ function _ETH2Deposit(uint256 _numDeposits) internal returns (uint256) { (bytes memory pubkeys, bytes memory signatures) = getOperators().assignNextSigningKeys(_numDeposits); if (pubkeys.length == 0) { return 0; } require(pubkeys.length.mod(PUBKEY_LENGTH) == 0, "REGISTRY_INCONSISTENT_PUBKEYS_LEN"); require(signatures.length.mod(SIGNATURE_LENGTH) == 0, "REGISTRY_INCONSISTENT_SIG_LEN"); uint256 numKeys = pubkeys.length.div(PUBKEY_LENGTH); require(numKeys == signatures.length.div(SIGNATURE_LENGTH), "REGISTRY_INCONSISTENT_SIG_COUNT"); for (uint256 i = 0; i < numKeys; ++i) { bytes memory pubkey = BytesLib.slice(pubkeys, i * PUBKEY_LENGTH, PUBKEY_LENGTH); bytes memory signature = BytesLib.slice(signatures, i * SIGNATURE_LENGTH, SIGNATURE_LENGTH); _stake(pubkey, signature); } DEPOSITED_VALIDATORS_POSITION.setStorageUint256( DEPOSITED_VALIDATORS_POSITION.getStorageUint256().add(numKeys) ); return numKeys.mul(DEPOSIT_SIZE); } /** * @dev Invokes a deposit call to the official Deposit contract * @param _pubkey Validator to stake for * @param _signature Signature of the deposit call */ function _stake(bytes memory _pubkey, bytes memory _signature) internal { bytes32 withdrawalCredentials = getWithdrawalCredentials(); require(withdrawalCredentials != 0, "EMPTY_WITHDRAWAL_CREDENTIALS"); uint256 value = DEPOSIT_SIZE; // The following computations and Merkle tree-ization will make official Deposit contract happy uint256 depositAmount = value.div(DEPOSIT_AMOUNT_UNIT); assert(depositAmount.mul(DEPOSIT_AMOUNT_UNIT) == value); // properly rounded // Compute deposit data root (`DepositData` hash tree root) according to deposit_contract.sol bytes32 pubkeyRoot = sha256(_pad64(_pubkey)); bytes32 signatureRoot = sha256( abi.encodePacked( sha256(BytesLib.slice(_signature, 0, 64)), sha256(_pad64(BytesLib.slice(_signature, 64, SIGNATURE_LENGTH.sub(64)))) ) ); bytes32 depositDataRoot = sha256( abi.encodePacked( sha256(abi.encodePacked(pubkeyRoot, withdrawalCredentials)), sha256(abi.encodePacked(_toLittleEndian64(depositAmount), signatureRoot)) ) ); uint256 targetBalance = address(this).balance.sub(value); getDepositContract().deposit.value(value)( _pubkey, abi.encodePacked(withdrawalCredentials), _signature, depositDataRoot); require(address(this).balance == targetBalance, "EXPECTING_DEPOSIT_TO_HAPPEN"); } /** * @dev Distributes rewards by minting and distributing corresponding amount of liquid tokens. * @param _totalRewards Total rewards accrued on the Ethereum 2.0 side in wei */ function distributeRewards(uint256 _totalRewards) internal { // We need to take a defined percentage of the reported reward as a fee, and we do // this by minting new token shares and assigning them to the fee recipients (see // StETH docs for the explanation of the shares mechanics). The staking rewards fee // is defined in basis points (1 basis point is equal to 0.01%, 10000 is 100%). // // Since we've increased totalPooledEther by _totalRewards (which is already // performed by the time this function is called), the combined cost of all holders' // shares has became _totalRewards StETH tokens more, effectively splitting the reward // between each token holder proportionally to their token share. // // Now we want to mint new shares to the fee recipient, so that the total cost of the // newly-minted shares exactly corresponds to the fee taken: // // shares2mint * newShareCost = (_totalRewards * feeBasis) / 10000 // newShareCost = newTotalPooledEther / (prevTotalShares + shares2mint) // // which follows to: // // _totalRewards * feeBasis * prevTotalShares // shares2mint = -------------------------------------------------------------- // (newTotalPooledEther * 10000) - (feeBasis * _totalRewards) // // The effect is that the given percentage of the reward goes to the fee recipient, and // the rest of the reward is distributed between token holders proportionally to their // token shares. uint256 feeBasis = _getFee(); uint256 shares2mint = ( _totalRewards.mul(feeBasis).mul(_getTotalShares()) .div( _getTotalPooledEther().mul(10000) .sub(feeBasis.mul(_totalRewards)) ) ); // Mint the calculated amount of shares to this contract address. This will reduce the // balances of the holders, as if the fee was taken in parts from each of them. _mintShares(address(this), shares2mint); (,uint16 insuranceFeeBasisPoints, uint16 operatorsFeeBasisPoints) = _getFeeDistribution(); uint256 toInsuranceFund = shares2mint.mul(insuranceFeeBasisPoints).div(10000); address insuranceFund = getInsuranceFund(); _transferShares(address(this), insuranceFund, toInsuranceFund); _emitTransferAfterMintingShares(insuranceFund, toInsuranceFund); uint256 distributedToOperatorsShares = _distributeNodeOperatorsReward( shares2mint.mul(operatorsFeeBasisPoints).div(10000) ); // Transfer the rest of the fee to treasury uint256 toTreasury = shares2mint.sub(toInsuranceFund).sub(distributedToOperatorsShares); address treasury = getTreasury(); _transferShares(address(this), treasury, toTreasury); _emitTransferAfterMintingShares(treasury, toTreasury); } function _distributeNodeOperatorsReward(uint256 _sharesToDistribute) internal returns (uint256 distributed) { (address[] memory recipients, uint256[] memory shares) = getOperators().getRewardsDistribution(_sharesToDistribute); assert(recipients.length == shares.length); distributed = 0; for (uint256 idx = 0; idx < recipients.length; ++idx) { _transferShares( address(this), recipients[idx], shares[idx] ); _emitTransferAfterMintingShares(recipients[idx], shares[idx]); distributed = distributed.add(shares[idx]); } } /** * @dev Records a deposit made by a user with optional referral * @param _sender sender's address * @param _value Deposit value in wei * @param _referral address of the referral */ function _submitted(address _sender, uint256 _value, address _referral) internal { BUFFERED_ETHER_POSITION.setStorageUint256(_getBufferedEther().add(_value)); emit Submitted(_sender, _value, _referral); } /** * @dev Records a deposit to the deposit_contract.deposit function. * @param _amount Total amount deposited to the ETH 2.0 side */ function _markAsUnbuffered(uint256 _amount) internal { BUFFERED_ETHER_POSITION.setStorageUint256( BUFFERED_ETHER_POSITION.getStorageUint256().sub(_amount)); emit Unbuffered(_amount); } /** * @dev Write a value nominated in basis points */ function _setBPValue(bytes32 _slot, uint16 _value) internal { require(_value <= 10000, "VALUE_OVER_100_PERCENT"); _slot.setStorageUint256(uint256(_value)); } /** * @dev Returns staking rewards fee rate */ function _getFee() internal view returns (uint16) { return _readBPValue(FEE_POSITION); } /** * @dev Returns fee distribution proportion */ function _getFeeDistribution() internal view returns (uint16 treasuryFeeBasisPoints, uint16 insuranceFeeBasisPoints, uint16 operatorsFeeBasisPoints) { treasuryFeeBasisPoints = _readBPValue(TREASURY_FEE_POSITION); insuranceFeeBasisPoints = _readBPValue(INSURANCE_FEE_POSITION); operatorsFeeBasisPoints = _readBPValue(NODE_OPERATORS_FEE_POSITION); } /** * @dev Read a value nominated in basis points */ function _readBPValue(bytes32 _slot) internal view returns (uint16) { uint256 v = _slot.getStorageUint256(); assert(v <= 10000); return uint16(v); } /** * @dev Gets the amount of Ether temporary buffered on this contract balance */ function _getBufferedEther() internal view returns (uint256) { uint256 buffered = BUFFERED_ETHER_POSITION.getStorageUint256(); assert(address(this).balance >= buffered); return buffered; } /** * @dev Gets unaccounted (excess) Ether on this contract balance */ function _getUnaccountedEther() internal view returns (uint256) { return address(this).balance.sub(_getBufferedEther()); } /** * @dev Calculates and returns the total base balance (multiple of 32) of validators in transient state, * i.e. submitted to the official Deposit contract but not yet visible in the beacon state. * @return transient balance in wei (1e-18 Ether) */ function _getTransientBalance() internal view returns (uint256) { uint256 depositedValidators = DEPOSITED_VALIDATORS_POSITION.getStorageUint256(); uint256 beaconValidators = BEACON_VALIDATORS_POSITION.getStorageUint256(); // beaconValidators can never be less than deposited ones. assert(depositedValidators >= beaconValidators); uint256 transientValidators = depositedValidators.sub(beaconValidators); return transientValidators.mul(DEPOSIT_SIZE); } /** * @dev Gets the total amount of Ether controlled by the system * @return total balance in wei */ function _getTotalPooledEther() internal view returns (uint256) { uint256 bufferedBalance = _getBufferedEther(); uint256 beaconBalance = BEACON_BALANCE_POSITION.getStorageUint256(); uint256 transientBalance = _getTransientBalance(); return bufferedBalance.add(beaconBalance).add(transientBalance); } /** * @dev Padding memory array with zeroes up to 64 bytes on the right * @param _b Memory array of size 32 .. 64 */ function _pad64(bytes memory _b) internal pure returns (bytes memory) { assert(_b.length >= 32 && _b.length <= 64); if (64 == _b.length) return _b; bytes memory zero32 = new bytes(32); assembly { mstore(add(zero32, 0x20), 0) } if (32 == _b.length) return BytesLib.concat(_b, zero32); else return BytesLib.concat(_b, BytesLib.slice(zero32, 0, uint256(64).sub(_b.length))); } /** * @dev Converting value to little endian bytes and padding up to 32 bytes on the right * @param _value Number less than `2**64` for compatibility reasons */ function _toLittleEndian64(uint256 _value) internal pure returns (uint256 result) { result = 0; uint256 temp_value = _value; for (uint256 i = 0; i < 8; ++i) { result = (result << 8) | (temp_value & 0xFF); temp_value >>= 8; } assert(0 == temp_value); // fully converted result <<= (24 * 8); } function to64(uint256 v) internal pure returns (uint64) { assert(v <= uint256(uint64(-1))); return uint64(v); } }
[{"constant":false,"inputs":[],"name":"resume","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[],"name":"stop","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_amount","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getInsuranceFund","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_ethAmount","type":"uint256"}],"name":"getSharesByPooledEth","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_sender","type":"address"},{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getOperators","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"DEPOSIT_SIZE","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getTotalPooledEther","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getTreasury","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isStopped","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBufferedEther","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SIGNATURE_LENGTH","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getWithdrawalCredentials","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_totalSupplyMult","type":"uint256"}],"name":"simulateBeaconRewards","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getFeeDistribution","outputs":[{"name":"treasuryFeeBasisPoints","type":"uint16"},{"name":"insuranceFeeBasisPoints","type":"uint16"},{"name":"operatorsFeeBasisPoints","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_sharesAmount","type":"uint256"}],"name":"getPooledEthByShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_oracle","type":"address"}],"name":"setOracle","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getOracle","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_treasuryFeeBasisPoints","type":"uint16"},{"name":"_insuranceFeeBasisPoints","type":"uint16"},{"name":"_operatorsFeeBasisPoints","type":"uint16"}],"name":"setFeeDistribution","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_feeBasisPoints","type":"uint16"}],"name":"setFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_maxDeposits","type":"uint256"}],"name":"depositBufferedEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"simulateBeaconRewards","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"_referral","type":"address"}],"name":"submit","outputs":[{"name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"WITHDRAWAL_CREDENTIALS_LENGTH","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"PUBKEY_LENGTH","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_amount","type":"uint256"},{"name":"_pubkeyHash","type":"bytes32"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getDepositContract","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBeaconStat","outputs":[{"name":"depositedValidators","type":"uint256"},{"name":"beaconValidators","type":"uint256"},{"name":"beaconBalance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_insuranceFund","type":"address"}],"name":"setInsuranceFund","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getFee","outputs":[{"name":"feeBasisPoints","type":"uint16"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getTotalShares","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_withdrawalCredentials","type":"bytes32"}],"name":"setWithdrawalCredentials","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"depositBufferedEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_beaconValidators","type":"uint256"},{"name":"_beaconBalance","type":"uint256"}],"name":"pushBeacon","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_account","type":"address"}],"name":"sharesOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"depositContract","type":"address"},{"name":"_oracle","type":"address"},{"name":"_operators","type":"address"},{"name":"_treasury","type":"address"},{"name":"_insuranceFund","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[],"name":"Stopped","type":"event"},{"anonymous":false,"inputs":[],"name":"Resumed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"feeBasisPoints","type":"uint16"}],"name":"FeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"treasuryFeeBasisPoints","type":"uint16"},{"indexed":false,"name":"insuranceFeeBasisPoints","type":"uint16"},{"indexed":false,"name":"operatorsFeeBasisPoints","type":"uint16"}],"name":"FeeDistributionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"withdrawalCredentials","type":"bytes32"}],"name":"WithdrawalCredentialsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"referral","type":"address"}],"name":"Submitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"Unbuffered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"tokenAmount","type":"uint256"},{"indexed":false,"name":"sentFromBuffer","type":"uint256"},{"indexed":true,"name":"pubkeyHash","type":"bytes32"},{"indexed":false,"name":"etherAmount","type":"uint256"}],"name":"Withdrawal","type":"event"}]
Contract Creation Code
608060405260028054600160a060020a031916331790553480156200002357600080fd5b5060405160a08062003f3183398101604090815281516020830151918301516060840151608090940151919390916200006585640100000000620000c0810204565b620000798464010000000062000191810204565b6200008d83640100000000620001dd810204565b620000a182640100000000620002ab810204565b620000b5816401000000006200036f810204565b505050505062000466565b620000d48164010000000062000433810204565b15156200014257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415f434f4e5452414354000000000000000000000000000000000000604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e6465706f736974436f6e747261637400000000000000815290519081900360190190206200018e90826401000000006200253d6200046282021704565b50565b604080517f6c69646f2e4c69646f2e6f7261636c6500000000000000000000000000000000815290519081900360100190206200018e90826401000000006200253d6200046282021704565b620001f18164010000000062000433810204565b15156200025f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415f434f4e5452414354000000000000000000000000000000000000604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e6e6f64654f70657261746f72735265676973747279008152905190819003601f0190206200018e90826401000000006200253d6200046282021704565b600160a060020a03811615156200032357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f5345545f54524541535552595f5a45524f5f4144445245535300000000000000604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e74726561737572790000000000000000000000000000815290519081900360120190206200018e90826401000000006200253d6200046282021704565b600160a060020a0381161515620003e757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5345545f494e535552414e43455f46554e445f5a45524f5f4144445245535300604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e696e737572616e636546756e64000000000000000000815290519081900360170190206200018e90826401000000006200253d6200046282021704565b600080600160a060020a03831615156200045157600091506200045c565b823b90506000811191505b50919050565b9055565b613abb80620004766000396000f3006080604052600436106102215763ffffffff60e060020a600035041663046f7da2811461028457806306fdde031461029b57806307da68f514610325578063095ea7b31461033a578063158626f71461037257806318160ddd146103a357806319208451146103ca57806323b872dd146103e257806327a099d81461040c578063313ce5671461042157806336bf33251461044c57806337cfdaca146103a357806339509351146104615780633b19e84a146104855780633f683b6a1461049a57806347b714e0146104af578063540bc5ea146104c457806356396715146104d957806370a08231146104ee578063727f9a511461050f578063752f77f1146105275780637a28fb88146105625780637adbf9731461057a578063833b1fce1461059b5780638cef3612146105b05780638e005553146105d857806390adc83b146105f457806395bf86ea1461060c57806395d89b4114610621578063a1903eab14610636578063a30448c01461064a578063a457c2d71461065f578063a4d55d1d14610683578063a8d2021a14610698578063a9059cbb146106b3578063ab94276a146106d7578063ae2e3538146106ec578063c3c052931461071f578063ced72f8714610740578063d5002f2e1461076c578063dd62ed3e14610781578063e97ee8cc146107a8578063ecc1dcfb146107c0578063f0f44260146107d5578063f16ac1fc146107f6578063f5eb42dc14610811578063f851a44014610832575b3615610277576040805160e560020a62461bcd02815260206004820152600e60248201527f4e4f4e5f454d5054595f44415441000000000000000000000000000000000000604482015290519081900360640190fd5b6102816000610847565b50005b34801561029057600080fd5b5061029961095b565b005b3480156102a757600080fd5b506102b0610965565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102ea5781810151838201526020016102d2565b50505050905090810190601f1680156103175780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561033157600080fd5b5061029961099c565b34801561034657600080fd5b5061035e600160a060020a03600435166024356109a4565b604080519115158252519081900360200190f35b34801561037e57600080fd5b506103876109ba565b60408051600160a060020a039092168252519081900360200190f35b3480156103af57600080fd5b506103b86109fd565b60408051918252519081900360200190f35b3480156103d657600080fd5b506103b8600435610a07565b3480156103ee57600080fd5b5061035e600160a060020a0360043581169060243516604435610a55565b34801561041857600080fd5b50610387610b27565b34801561042d57600080fd5b50610436610b65565b6040805160ff9092168252519081900360200190f35b34801561045857600080fd5b506103b8610b6a565b34801561046d57600080fd5b5061035e600160a060020a0360043516602435610b77565b34801561049157600080fd5b50610387610bb3565b3480156104a657600080fd5b5061035e610bf1565b3480156104bb57600080fd5b506103b8610c23565b3480156104d057600080fd5b506103b8610c2d565b3480156104e557600080fd5b506103b8610c32565b3480156104fa57600080fd5b506103b8600160a060020a0360043516610c70565b34801561051b57600080fd5b50610299600435610c89565b34801561053357600080fd5b5061053c610d34565b6040805161ffff9485168152928416602084015292168183015290519081900360600190f35b34801561056e57600080fd5b506103b8600435610d4c565b34801561058657600080fd5b50610299600160a060020a0360043516610d78565b3480156105a757600080fd5b50610387610dd4565b3480156105bc57600080fd5b5061029961ffff60043581169060243581169060443516610e12565b3480156105e457600080fd5b5061029961ffff60043516610fe8565b34801561060057600080fd5b506102996004356110ae565b34801561061857600080fd5b506102996110b7565b34801561062d57600080fd5b506102b06110c8565b6103b8600160a060020a03600435166110ff565b34801561065657600080fd5b506103b861110a565b34801561066b57600080fd5b5061035e600160a060020a036004351660243561110f565b34801561068f57600080fd5b506103b86111ac565b3480156106a457600080fd5b506102996004356024356111b1565b3480156106bf57600080fd5b5061035e600160a060020a036004351660243561126e565b3480156106e357600080fd5b5061038761127b565b3480156106f857600080fd5b506107016112b9565b60408051938452602084019290925282820152519081900360600190f35b34801561072b57600080fd5b50610299600160a060020a0360043516611348565b34801561074c57600080fd5b506107556113a1565b6040805161ffff9092168252519081900360200190f35b34801561077857600080fd5b506103b86113ab565b34801561078d57600080fd5b506103b8600160a060020a03600435811690602435166113b5565b3480156107b457600080fd5b506102996004356113e0565b3480156107cc57600080fd5b50610299611506565b3480156107e157600080fd5b50610299600160a060020a0360043516611510565b34801561080257600080fd5b50610299600435602435611569565b34801561081d57600080fd5b506103b8600160a060020a036004351661183a565b34801561083e57600080fd5b50610387611845565b60408051600080516020613a108339815191528152905190819003601801902060009081908190819061087990611854565b15156108bd576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613a50833981519152604482015290519081900360640190fd5b33925034915081151561091a576040805160e560020a62461bcd02815260206004820152600c60248201527f5a45524f5f4445504f5349540000000000000000000000000000000000000000604482015290519081900360640190fd5b61092382610a07565b905080151561092f5750805b6109398382611858565b506109458383876119c3565b61094f8382611a5a565b8093505b505050919050565b610963611aa5565b565b60408051808201909152601781527f4c6971756964207374616b656420457468657220322e30000000000000000000602082015290565b610963611b7f565b60006109b1338484611c48565b50600192915050565b604080517f6c69646f2e4c69646f2e696e737572616e636546756e64000000000000000000815290519081900360170190206000906109f890611854565b905090565b60006109f8611dd7565b600080610a12611dd7565b9050801515610a245760009150610a4f565b610a4c81610a40610a33611e39565b869063ffffffff611e7716565b9063ffffffff611f6616565b91505b50919050565b600160a060020a038316600090815260016020908152604080832033845290915281205482811015610af7576040805160e560020a62461bcd02815260206004820152602160248201527f5452414e534645525f414d4f554e545f455843454544535f414c4c4f57414e4360448201527f4500000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b610b02858585612006565b610b1c8533610b17848763ffffffff61206f16565b611c48565b506001949350505050565b604080517f6c69646f2e4c69646f2e6e6f64654f70657261746f72735265676973747279008152905190819003601f0190206000906109f890611854565b601290565b6801bc16d674ec80000081565b336000818152600160209081526040808320600160a060020a038716845290915281205490916109b1918590610b17908663ffffffff61210316565b604080517f6c69646f2e4c69646f2e74726561737572790000000000000000000000000000815290519081900360120190206000906109f890611854565b60408051600080516020613a1083398151915281529051908190036018019020600090610c1d90611854565b15905090565b60006109f8612191565b606081565b604080517f6c69646f2e4c69646f2e7769746864726177616c43726564656e7469616c73008152905190819003601f0190206000906109f890611854565b6000610c83610c7e836121e3565b610d4c565b92915050565b600080600080610c97611dd7565b9350670de0b6b3a764000085850260408051600080516020613a708339815191528152905190819003601a0190209190049350610cd390611854565b604080516000805160206139f083398151915281529051908190036017019020909250610cff90611854565b9050610d2184610d15838663ffffffff61210316565b9063ffffffff61206f16565b9050610d2d8282611569565b5050505050565b6000806000610d416121fe565b925092509250909192565b600080610d57611e39565b9050801515610d695760009150610a4f565b610a4c81610a40610a33611dd7565b600254600160a060020a03163314610dc8576040805160e560020a62461bcd02815260206004820152600c60248201526000805160206139d0833981519152604482015290519081900360640190fd5b610dd1816122bd565b50565b604080517f6c69646f2e4c69646f2e6f7261636c6500000000000000000000000000000000815290519081900360100190206000906109f890611854565b600254600160a060020a03163314610e62576040805160e560020a62461bcd02815260206004820152600c60248201526000805160206139d0833981519152604482015290519081900360640190fd5b610e918161ffff16610e858461ffff168661ffff1661210390919063ffffffff16565b9063ffffffff61210316565b61271014610ee9576040805160e560020a62461bcd02815260206004820152601060248201527f464545535f444f4e545f4144445f555000000000000000000000000000000000604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e7472656173757279466565000000000000000000000081529051908190036015019020610f2590846122ff565b604080517f6c69646f2e4c69646f2e696e737572616e63654665650000000000000000000081529051908190036016019020610f6190836122ff565b604080517f6c69646f2e4c69646f2e6e6f64654f70657261746f72734665650000000000008152905190819003601a019020610f9d90826122ff565b6040805161ffff8086168252808516602083015283168183015290517f034529db1bba3830b8877e116871f19c5b96ef86c739f2a05668c860c84668989181900360600190a1505050565b600254600160a060020a03163314611038576040805160e560020a62461bcd02815260206004820152600c60248201526000805160206139d0833981519152604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e666565000000000000000000000000000000000000008152905190819003600d01902061107490826122ff565b6040805161ffff8316815290517faab062e3faf62b6c9a0f8e62af66e0310e27127a8c871a67be7dd4d93de6da539181900360200190a150565b610dd181612375565b610963670e043da617250000610c89565b60408051808201909152600581527f7374455448000000000000000000000000000000000000000000000000000000602082015290565b6000610c8382610847565b602081565b336000908152600160209081526040808320600160a060020a03861684529091528120548281101561118b576040805160e560020a62461bcd02815260206004820152601e60248201527f4445435245415345445f414c4c4f57414e43455f42454c4f575f5a45524f0000604482015290519081900360640190fd5b6111a03385610b17848763ffffffff61206f16565b600191505b5092915050565b603081565b60408051600080516020613a10833981519152815290519081900360180190206111da90611854565b151561121e576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613a50833981519152604482015290519081900360640190fd5b6040805160e560020a62461bcd02815260206004820152601360248201527f4e4f545f494d504c454d454e5445445f59455400000000000000000000000000604482015290519081900360640190fd5b60006109b1338484612006565b604080517f6c69646f2e4c69646f2e6465706f736974436f6e747261637400000000000000815290519081900360190190206000906109f890611854565b60408051600080516020613a308339815191528152905190819003601d019020600090819081906112e990611854565b60408051600080516020613a708339815191528152905190819003601a01902090935061131590611854565b604080516000805160206139f08339815191528152905190819003601701902090925061134190611854565b9050909192565b600254600160a060020a03163314611398576040805160e560020a62461bcd02815260206004820152600c60248201526000805160206139d0833981519152604482015290519081900360640190fd5b610dd18161245d565b60006109f86124ff565b60006109f8611e39565b600160a060020a03918216600090815260016020908152604080832093909416825291909152205490565b600254600160a060020a03163314611430576040805160e560020a62461bcd02815260206004820152600c60248201526000805160206139d0833981519152604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e7769746864726177616c43726564656e7469616c73008152905190819003601f019020611472908263ffffffff61253d16565b61147a610b27565b600160a060020a031663f778021e6040518163ffffffff1660e060020a028152600401600060405180830381600087803b1580156114b757600080fd5b505af11580156114cb573d6000803e3d6000fd5b50506040805184815290517f13eb80e900aa05a2696d50d5de33ef631c73493c4921da233b17335ff6b7b1149350908190036020019150a150565b6109636010612375565b600254600160a060020a03163314611560576040805160e560020a62461bcd02815260206004820152600c60248201526000805160206139d0833981519152604482015290519081900360640190fd5b610dd181612541565b60008060008060006115a16040518080600080516020613a108339815191528152506018019050604051809103902060001916611854565b15156115e5576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613a50833981519152604482015290519081900360640190fd5b6115ed610dd4565b600160a060020a0316331461164c576040805160e560020a62461bcd02815260206004820152600f60248201527f4150505f415554485f4641494c45440000000000000000000000000000000000604482015290519081900360640190fd5b60408051600080516020613a308339815191528152905190819003601d01902061167590611854565b9450848711156116cf576040805160e560020a62461bcd02815260206004820152601760248201527f5245504f525445445f4d4f52455f4445504f5349544544000000000000000000604482015290519081900360640190fd5b60408051600080516020613a708339815191528152905190819003601a0190206116f890611854565b935083871015611752576040805160e560020a62461bcd02815260206004820152601860248201527f5245504f525445445f4c4553535f56414c494441544f52530000000000000000604482015290519081900360640190fd5b611762878563ffffffff61206f16565b604080516000805160206139f0833981519152815290519081900360170190209093506117ab9061179290611854565b610e85856801bc16d674ec80000063ffffffff611e7716565b604080516000805160206139f0833981519152815290519081900360170190209092506117de908763ffffffff61253d16565b60408051600080516020613a708339815191528152905190819003601a01902061180e908863ffffffff61253d16565b8186111561183157611826868363ffffffff61206f16565b9050611831816125e3565b50505050505050565b6000610c83826121e3565b600254600160a060020a031681565b5490565b60408051600080516020613a108339815191528152905190819003601801902060009061188490611854565b15156118c8576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613a50833981519152604482015290519081900360640190fd5b600160a060020a0383161515611928576040805160e560020a62461bcd02815260206004820152601860248201527f4d494e545f544f5f5448455f5a45524f5f414444524553530000000000000000604482015290519081900360640190fd5b61193482610e85611e39565b604080517f6c69646f2e53744554482e746f74616c5368617265730000000000000000000081529051908190036016019020909150611979908263ffffffff61253d16565b600160a060020a0383166000908152602081905260409020546119a2908363ffffffff61210316565b600160a060020a039093166000908152602081905260409020929092555090565b611a106119d283610e85612191565b604080517f6c69646f2e4c69646f2e62756666657265644574686572000000000000000000815290519081900360170190209063ffffffff61253d16565b60408051838152600160a060020a0383811660208301528251908616927f96a25c8ce0baabc1fdefd93e9ed25d8e092a3332f3aa9a41722b5697231d1d1a928290030190a2505050565b600160a060020a03821660007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef611a9084610d4c565b60408051918252519081900360200190a35050565b60408051600080516020613a1083398151915281529051908190036018019020611ace90611854565b15611b23576040805160e560020a62461bcd02815260206004820152601260248201527f434f4e54524143545f49535f4143544956450000000000000000000000000000604482015290519081900360640190fd5b60408051600080516020613a1083398151915281529051908190036018019020611b5490600163ffffffff61253d16565b6040517f62451d457bc659158be6e6247f56ec1df424a5c7597f71c20c2bc44e0965c8f990600090a1565b60408051600080516020613a1083398151915281529051908190036018019020611ba890611854565b1515611bec576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613a50833981519152604482015290519081900360640190fd5b60408051600080516020613a1083398151915281529051908190036018019020611c1d90600063ffffffff61253d16565b6040517f7acc84e34091ae817647a4c49116f5cc07f319078ba80f8f5fde37ea7e25cbd690600090a1565b60408051600080516020613a1083398151915281529051908190036018019020611c7190611854565b1515611cb5576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613a50833981519152604482015290519081900360640190fd5b600160a060020a0383161515611d15576040805160e560020a62461bcd02815260206004820152601960248201527f415050524f56455f46524f4d5f5a45524f5f4144445245535300000000000000604482015290519081900360640190fd5b600160a060020a0382161515611d75576040805160e560020a62461bcd02815260206004820152601760248201527f415050524f56455f544f5f5a45524f5f41444452455353000000000000000000604482015290519081900360640190fd5b600160a060020a03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b600080600080611de5612191565b604080516000805160206139f083398151915281529051908190036017019020909350611e1190611854565b9150611e1b612706565b9050611e3181610e85858563ffffffff61210316565b935050505090565b604080517f6c69646f2e53744554482e746f74616c53686172657300000000000000000000815290519081900360160190206000906109f890611854565b600080831515611e8a57600091506111a5565b50828202828482811515611e9a57fe5b60408051808201909152601181527f4d4154485f4d554c5f4f564552464c4f5700000000000000000000000000000060208201529291900414611f5e5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611f23578181015183820152602001611f0b565b50505050905090810190601f168015611f505780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509392505050565b60408051808201909152600d81527f4d4154485f4449565f5a45524f0000000000000000000000000000000000000060208201526000908190818411611ff15760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015611f23578181015183820152602001611f0b565b508284811515611ffd57fe5b04949350505050565b600061201182610a07565b905061201e84848361279b565b82600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a350505050565b60408051808201909152601281527f4d4154485f5355425f554e444552464c4f57000000000000000000000000000060208201526000908190848411156120fb5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015611f23578181015183820152602001611f0b565b505050900390565b60408051808201909152601181527f4d4154485f4144445f4f564552464c4f5700000000000000000000000000000060208201526000908383019084821015611f5e5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015611f23578181015183820152602001611f0b565b604080517f6c69646f2e4c69646f2e627566666572656445746865720000000000000000008152905190819003601701902060009081906121d190611854565b905030318111156121de57fe5b919050565b600160a060020a031660009081526020819052604090205490565b600080600061224160405180807f6c69646f2e4c69646f2e74726561737572794665650000000000000000000000815250601501905060405180910390206129a4565b604080517f6c69646f2e4c69646f2e696e737572616e6365466565000000000000000000008152905190819003601601902090935061227f906129a4565b604080517f6c69646f2e4c69646f2e6e6f64654f70657261746f72734665650000000000008152905190819003601a019020909250611341906129a4565b604080517f6c69646f2e4c69646f2e6f7261636c650000000000000000000000000000000081529051908190036010019020610dd1908263ffffffff61253d16565b61271061ffff8216111561235d576040805160e560020a62461bcd02815260206004820152601660248201527f56414c55455f4f5645525f3130305f50455243454e5400000000000000000000604482015290519081900360640190fd5b6123718261ffff831663ffffffff61253d16565b5050565b60408051600080516020613a1083398151915281529051908190036018019020600090819081906123a590611854565b15156123e9576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613a50833981519152604482015290519081900360640190fd5b6123f1612191565b92506801bc16d674ec80000083106124575761240b6129c2565b9150612426836801bc16d674ec80000063ffffffff611f6616565b905061244761244285831061243b578561243d565b825b6129dd565b612d5f565b816124506129c2565b1461245757fe5b50505050565b600160a060020a03811615156124bd576040805160e560020a62461bcd02815260206004820152601f60248201527f5345545f494e535552414e43455f46554e445f5a45524f5f4144445245535300604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e696e737572616e636546756e6400000000000000000081529051908190036017019020610dd1908263ffffffff61253d16565b604080517f6c69646f2e4c69646f2e666565000000000000000000000000000000000000008152905190819003600d0190206000906109f8906129a4565b9055565b600160a060020a03811615156125a1576040805160e560020a62461bcd02815260206004820152601960248201527f5345545f54524541535552595f5a45524f5f4144445245535300000000000000604482015290519081900360640190fd5b604080517f6c69646f2e4c69646f2e7472656173757279000000000000000000000000000081529051908190036012019020610dd1908263ffffffff61253d16565b60008060008060008060008060006125f96124ff565b61ffff16985061264a61262f6126158b8d63ffffffff611e7716565b610d15612710612623611dd7565b9063ffffffff611e7716565b610a4061263a611e39565b6126238e8e63ffffffff611e7716565b97506126563089611858565b5061265f6121fe565b90985096506126809050612710610a408a61ffff8b1663ffffffff611e7716565b945061268a6109ba565b935061269730858761279b565b6126a18486611a5a565b6126c36126be612710610a408b61ffff8b1663ffffffff611e7716565b612dda565b92506126d983610d158a8863ffffffff61206f16565b91506126e3610bb3565b90506126f030828461279b565b6126fa8183611a5a565b50505050505050505050565b60408051600080516020613a308339815191528152905190819003601d01902060009081908190819061273890611854565b60408051600080516020613a708339815191528152905190819003601a01902090935061276490611854565b91508183101561277057fe5b612780838363ffffffff61206f16565b9050611e31816801bc16d674ec80000063ffffffff611e7716565b60408051600080516020613a10833981519152815290519081900360180190206000906127c790611854565b151561280b576040805160e560020a62461bcd0281526020600482015260136024820152600080516020613a50833981519152604482015290519081900360640190fd5b600160a060020a038416151561286b576040805160e560020a62461bcd02815260206004820152601e60248201527f5452414e534645525f46524f4d5f5448455f5a45524f5f414444524553530000604482015290519081900360640190fd5b600160a060020a03831615156128cb576040805160e560020a62461bcd02815260206004820152601c60248201527f5452414e534645525f544f5f5448455f5a45524f5f4144445245535300000000604482015290519081900360640190fd5b50600160a060020a0383166000908152602081905260409020548082111561293d576040805160e560020a62461bcd02815260206004820152601f60248201527f5452414e534645525f414d4f554e545f455843454544535f42414c414e434500604482015290519081900360640190fd5b61294d818363ffffffff61206f16565b600160a060020a038086166000908152602081905260408082209390935590851681522054612982908363ffffffff61210316565b600160a060020a03909316600090815260208190526040902092909255505050565b6000806129b083611854565b9050612710811115610c8357fe5b9055565b60006109f86129cf612191565b30319063ffffffff61206f16565b60006060806000806060806129f0610b27565b600160a060020a03166341bc716f896040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b158015612a3857600080fd5b505af1158015612a4c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040908152811015612a7557600080fd5b810190808051640100000000811115612a8d57600080fd5b82016020810184811115612aa057600080fd5b8151640100000000811182820187101715612aba57600080fd5b50509291906020018051640100000000811115612ad657600080fd5b82016020810184811115612ae957600080fd5b8151640100000000811182820187101715612b0357600080fd5b50508451949a50985050509015159050612b205760009650612d54565b8551612b3390603063ffffffff612fce16565b15612bae576040805160e560020a62461bcd02815260206004820152602160248201527f52454749535452595f494e434f4e53495354454e545f5055424b4559535f4c4560448201527f4e00000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b8451612bc190606063ffffffff612fce16565b15612c16576040805160e560020a62461bcd02815260206004820152601d60248201527f52454749535452595f494e434f4e53495354454e545f5349475f4c454e000000604482015290519081900360640190fd5b8551612c2990603063ffffffff611f6616565b8551909450612c3f90606063ffffffff611f6616565b8414612c95576040805160e560020a62461bcd02815260206004820152601f60248201527f52454749535452595f494e434f4e53495354454e545f5349475f434f554e5400604482015290519081900360640190fd5b600092505b83831015612cd957612cb18660308502603061306b565b9150612cc28560608502606061306b565b9050612cce82826130ec565b826001019250612c9a565b60408051600080516020613a308339815191528152905190819003601d019020612d3890612d0c908690610e8590611854565b60408051600080516020613a308339815191528152905190819003601d0190209063ffffffff61253d16565b612d51846801bc16d674ec80000063ffffffff611e7716565b96505b505050505050919050565b604080517f6c69646f2e4c69646f2e6275666665726564457468657200000000000000000081529051908190036017019020612da4906119d2908390610d1590611854565b6040805182815290517f76a397bea5768d4fca97ef47792796e35f98dc81b16c1de84e28a818e1f971089181900360200190a150565b60006060806000612de9610b27565b600160a060020a03166362dcfda1866040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b158015612e3157600080fd5b505af1158015612e45573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040908152811015612e6e57600080fd5b810190808051640100000000811115612e8657600080fd5b82016020810184811115612e9957600080fd5b8151856020820283011164010000000082111715612eb657600080fd5b50509291906020018051640100000000811115612ed257600080fd5b82016020810184811115612ee557600080fd5b8151856020820283011164010000000082111715612f0257600080fd5b50509291905050509250925081518351141515612f1b57fe5b5060009250825b825181101561095357612f64308483815181101515612f3d57fe5b906020019060200201518484815181101515612f5557fe5b9060200190602002015161279b565b612f9c8382815181101515612f7557fe5b906020019060200201518383815181101515612f8d57fe5b90602001906020020151611a5a565b612fc48282815181101515612fad57fe5b60209081029091010151859063ffffffff61210316565b9350600101612f22565b60408051808201909152600d81527f4d4154485f4449565f5a45524f0000000000000000000000000000000000000060208201526000908215156130575760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015611f23578181015183820152602001611f0b565b50818381151561306357fe5b069392505050565b60608082840185511015151561308057600080fd5b82158015613099576040519150602082016040526130e3565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156130d25780518352602092830192016130ba565b5050858452601f01601f1916604052505b50949350505050565b60008060008060008060006130ff610c32565b9650861515613158576040805160e560020a62461bcd02815260206004820152601c60248201527f454d5054595f5749544844524157414c5f43524544454e5449414c5300000000604482015290519081900360640190fd5b6801bc16d674ec800000955061317886633b9aca0063ffffffff611f6616565b94508561318f86633b9aca0063ffffffff611e7716565b1461319657fe5b60026131a18a613874565b6040518082805190602001908083835b602083106131d05780518252601f1990920191602091820191016131b1565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015613211573d6000803e3d6000fd5b5050506040513d602081101561322657600080fd5b5051935060028061323a8a6000604061306b565b6040518082805190602001908083835b602083106132695780518252601f19909201916020918201910161324a565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af11580156132aa573d6000803e3d6000fd5b5050506040513d60208110156132bf57600080fd5b505160026132e76132e28c60406132dd60608263ffffffff61206f16565b61306b565b613874565b6040518082805190602001908083835b602083106133165780518252601f1990920191602091820191016132f7565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015613357573d6000803e3d6000fd5b5050506040513d602081101561336c57600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b602083106133c25780518252601f1990920191602091820191016133a3565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015613403573d6000803e3d6000fd5b5050506040513d602081101561341857600080fd5b50516040805160208181018890528183018b905282518083038401815260609092019283905281519396506002938493918291908401908083835b602083106134725780518252601f199092019160209182019101613453565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af11580156134b3573d6000803e3d6000fd5b5050506040513d60208110156134c857600080fd5b505160026134d588613904565b60408051602080820193909352808201899052815180820383018152606090910191829052805190928291908401908083835b602083106135275780518252601f199092019160209182019101613508565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015613568573d6000803e3d6000fd5b5050506040513d602081101561357d57600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b602083106135d35780518252601f1990920191602091820191016135b4565b51815160209384036101000a600019018019909216911617905260405191909301945091925050808303816000865af1158015613614573d6000803e3d6000fd5b5050506040513d602081101561362957600080fd5b5051915061363e30318763ffffffff61206f16565b905061364861127b565b600160a060020a03166322895118878b8a6040516020018082600019166000191681526020019150506040516020818303038152906040528c876040518663ffffffff1660e060020a028152600401808060200180602001806020018560001916600019168152602001848103845288818151815260200191508051906020019080838360005b838110156136e75781810151838201526020016136cf565b50505050905090810190601f1680156137145780820380516001836020036101000a031916815260200191505b50848103835287518152875160209182019189019080838360005b8381101561374757818101518382015260200161372f565b50505050905090810190601f1680156137745780820380516001836020036101000a031916815260200191505b50848103825286518152865160209182019188019080838360005b838110156137a757818101518382015260200161378f565b50505050905090810190601f1680156137d45780820380516001836020036101000a031916815260200191505b509750505050505050506000604051808303818588803b1580156137f757600080fd5b505af115801561380b573d6000803e3d6000fd5b50505050303182149050613869576040805160e560020a62461bcd02815260206004820152601b60248201527f455850454354494e475f4445504f5349545f544f5f48415050454e0000000000604482015290519081900360640190fd5b505050505050505050565b606080602083511015801561388b57506040835111155b151561389357fe5b8251604014156138a557829150610a4f565b6040805160208082528183019092529080820161040080388339019050509050600060208201528251602014156138e057610a4c8382613954565b610a4c836138ff8360006132dd8851604061206f90919063ffffffff16565b613954565b600081815b600881101561392a5761010092830260ff8316179290910490600101613909565b811561393257fe5b5050780100000000000000000000000000000000000000000000000002919050565b6060806040519050835180825260208201818101602087015b8183101561398557805183526020928301920161396d565b50855184518101855292509050808201602086015b818310156139b257805183526020928301920161399a565b509551919091011594909401601f01601f191660405293925050505600554e415554484f52495a454400000000000000000000000000000000000000006c69646f2e4c69646f2e626561636f6e42616c616e63650000000000000000006c69646f2e5061757361626c652e616374697665466c616700000000000000006c69646f2e4c69646f2e6465706f736974656456616c696461746f7273000000434f4e54524143545f49535f53544f50504544000000000000000000000000006c69646f2e4c69646f2e626561636f6e56616c696461746f7273000000000000a165627a7a72305820901141453bed940aab639f2821e61b7adb872d37a602b2f7d3b2bb33946e5ad7002900000000000000000000000019170c315d1fe30c8654a1caab992a7edfd6f35600000000000000000000000002139137fdd974181a49268d7b0ae888634e546900000000000000000000000032c6f34f3920e8c0074241619c02be2fb722a68d00000000000000000000000002139137fdd974181a49268d7b0ae888634e546900000000000000000000000002139137fdd974181a49268d7b0ae888634e5469
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000019170c315d1fe30c8654a1caab992a7edfd6f35600000000000000000000000002139137fdd974181a49268d7b0ae888634e546900000000000000000000000032c6f34f3920e8c0074241619c02be2fb722a68d00000000000000000000000002139137fdd974181a49268d7b0ae888634e546900000000000000000000000002139137fdd974181a49268d7b0ae888634e5469
-----Decoded View---------------
Arg [0] : depositContract (address): 0x19170c315d1fe30c8654a1caab992a7edfd6f356
Arg [1] : _oracle (address): 0x02139137fdd974181a49268d7b0ae888634e5469
Arg [2] : _operators (address): 0x32c6f34f3920e8c0074241619c02be2fb722a68d
Arg [3] : _treasury (address): 0x02139137fdd974181a49268d7b0ae888634e5469
Arg [4] : _insuranceFund (address): 0x02139137fdd974181a49268d7b0ae888634e5469
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 00000000000000000000000019170c315d1fe30c8654a1caab992a7edfd6f356
Arg [1] : 00000000000000000000000002139137fdd974181a49268d7b0ae888634e5469
Arg [2] : 00000000000000000000000032c6f34f3920e8c0074241619c02be2fb722a68d
Arg [3] : 00000000000000000000000002139137fdd974181a49268d7b0ae888634e5469
Arg [4] : 00000000000000000000000002139137fdd974181a49268d7b0ae888634e5469
Deployed ByteCode Sourcemap
55386:30265:0:-;;;;;;;;;-1:-1:-1;;;55386:30265:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59165:8;:20;59157:47;;;;;-1:-1:-1;;;;;59157:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;59215:10;59223:1;59215:7;:10::i;:::-;;55386:30265;60462:55;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60462:55:0;;;;;;41528:96;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41528:96:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;41528:96:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60336:51;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60336:51:0;;;;44564:154;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;44564:154:0;-1:-1:-1;;;;;44564:154:0;;;;;;;;;;;;;;;;;;;;;;;;;69518:127;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69518:127:0;;;;;;;;-1:-1:-1;;;;;69518:127:0;;;;;;;;;;;;;;42244:101;;8:9:-1;5:2;;;30:1;27;20:12;5:2;42244:101:0;;;;;;;;;;;;;;;;;;;;48367:351;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;48367:351:0;;;;;45490:404;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;45490:404:0;-1:-1:-1;;;;;45490:404:0;;;;;;;;;;;;69079:171;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69079:171:0;;;;41934:76;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41934:76:0;;;;;;;;;;;;;;;;;;;;;;;55716:47;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55716:47:0;;;;46459:210;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;46459:210:0;-1:-1:-1;;;;;46459:210:0;;;;;;;69323:116;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69323:116:0;;;;37709:114;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37709:114:0;;;;68428:105;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68428:105:0;;;;55662:45;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55662:45:0;;;;67946:143;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67946:143:0;;;;42902:134;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;42902:134:0;-1:-1:-1;;;;;42902:134:0;;;;;64689:503;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;64689:503:0;;;;;67535:277;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67535:277:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48830:342;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;48830:342:0;;;;;62274:138;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;62274:138:0;-1:-1:-1;;;;;62274:138:0;;;;;68877:112;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68877:112:0;;;;61207:806;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;61207:806:0;;;;;;;;;;;;;;;;;60724:204;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;60724:204:0;;;;;;;60141:122;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;60141:122:0;;;;;64580:101;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64580:101:0;;;;41738:80;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41738:80:0;;;;59476:114;;-1:-1:-1;;;;;59476:114:0;;;;;55597:58;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55597:58:0;;;;47323:364;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;47323:364:0;-1:-1:-1;;;;;47323:364:0;;;;;;;55548:42;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55548:42:0;;;;64158:414;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;64158:414:0;;;;;;;43551:160;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;43551:160:0;-1:-1:-1;;;;;43551:160:0;;;;;;;68606:158;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68606:158:0;;;;70020:360;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70020:360:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63061:166;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;63061:166:0;-1:-1:-1;;;;;63061:166:0;;;;;67356:99;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67356:99:0;;;;;;;;;;;;;;;;;;;;;;;47950;;8:9:-1;5:2;;;30:1;27;20:12;5:2;47950:99:0;;;;43983:137;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;43983:137:0;-1:-1:-1;;;;;43983:137:0;;;;;;;;;;63640:332;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;63640:332:0;;;;;59778:119;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59778:119:0;;;;62655:146;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;62655:146:0;-1:-1:-1;;;;;62655:146:0;;;;;65537:1742;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;65537:1742:0;;;;;;;48133:111;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;48133:111:0;-1:-1:-1;;;;;48133:111:0;;;;;57820:33;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57820:33:0;;;;71903:702;37398:37;;;-1:-1:-1;;;;;;;;;;;37398:37:0;;;;;;;;;;;;71972:7;;;;;;;;37489:37;;:35;:37::i;:::-;37481:69;;;;;;;-1:-1:-1;;;;;37481:69:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;37481:69:0;;;;;;;;;;;;;;;72009:10;;-1:-1:-1;72048:9:0;;-1:-1:-1;72076:12:0;;;72068:37;;;;;-1:-1:-1;;;;;72068:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;72141:29;72162:7;72141:20;:29::i;:::-;72118:52;-1:-1:-1;72185:17:0;;72181:228;;;-1:-1:-1;72390:7:0;72181:228;72421:33;72433:6;72441:12;72421:11;:33::i;:::-;;72465:38;72476:6;72484:7;72493:9;72465:10;:38::i;:::-;72514:53;72546:6;72554:12;72514:31;:53::i;:::-;72585:12;72578:19;;37561:1;71903:702;;;;;;:::o;60462:55::-;60500:9;:7;:9::i;:::-;60462:55::o;41528:96::-;41584:32;;;;;;;;;;;;;;;;;41528:96;:::o;60336:51::-;60372:7;:5;:7::i;44564:154::-;44632:4;44649:39;44658:10;44670:8;44680:7;44649:8;:39::i;:::-;-1:-1:-1;44706:4:0;44564:154;;;;:::o;69518:127::-;56824:36;;;;;;;;;;;;;;;;69567:7;;69594:43;;:41;:43::i;:::-;69587:50;;69518:127;:::o;42244:101::-;42288:7;42315:22;:20;:22::i;48367:351::-;48438:7;48458:24;48485:22;:20;:22::i;:::-;48458:49;-1:-1:-1;48522:21:0;;48518:193;;;48567:1;48560:8;;;;48518:193;48608:91;48682:16;48608:51;48641:17;:15;:17::i;:::-;48608:10;;:51;:32;:51;:::i;:::-;:73;:91;:73;:91;:::i;:::-;48601:98;;48518:193;48367:351;;;;:::o;45490:404::-;-1:-1:-1;;;;;45626:19:0;;45582:4;45626:19;;;:10;:19;;;;;;;;45646:10;45626:31;;;;;;;;45676:27;;;;45668:73;;;;;-1:-1:-1;;;;;45668:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45754:39;45764:7;45773:10;45785:7;45754:9;:39::i;:::-;45804:60;45813:7;45822:10;45834:29;:16;45855:7;45834:29;:20;:29;:::i;:::-;45804:8;:60::i;:::-;-1:-1:-1;45882:4:0;;45490:404;-1:-1:-1;;;;45490:404:0:o;69079:171::-;56637:44;;;;;;;;;;;;;;;;69124:22;;69189:52;;:50;:52::i;41934:76::-;42000:2;41934:76;:::o;55716:47::-;55755:8;55716:47;:::o;46459:210::-;46567:10;46541:4;46589:22;;;:10;:22;;;;;;;;-1:-1:-1;;;;;46589:32:0;;;;;;;;;;46541:4;;46558:81;;46579:8;;46589:49;;46626:11;46589:49;:36;:49;:::i;69323:116::-;56734:31;;;;;;;;;;;;;;;;69367:7;;69394:37;;:35;:37::i;37709:114::-;37398:37;;;-1:-1:-1;;;;;;;;;;;37398:37:0;;;;;;;;;;;;37753:4;;37778:37;;:35;:37::i;:::-;37777:38;37770:45;;37709:114;:::o;68428:105::-;68479:7;68506:19;:17;:19::i;55662:45::-;55705:2;55662:45;:::o;67946:143::-;57767:44;;;;;;;;;;;;;;;;68003:7;;68030:51;;:49;:51::i;42902:134::-;42960:7;42987:41;43008:19;43018:8;43008:9;:19::i;:::-;42987:20;:41::i;:::-;42980:48;42902:134;-1:-1:-1;;42902:134:0:o;64689:503::-;64764:19;64819:22;64898:24;64982:21;64786:22;:20;:22::i;:::-;64764:44;-1:-1:-1;64879:6:0;64845:30;;;57578:39;;;-1:-1:-1;;;;;;;;;;;57578:39:0;;;;;;;;;;;;64844:41;;;;-1:-1:-1;64925:46:0;;:44;:46::i;:::-;57408:36;;;-1:-1:-1;;;;;;;;;;;57408:36:0;;;;;;;;;;;;64898:73;;-1:-1:-1;65006:43:0;;:41;:43::i;:::-;64982:67;-1:-1:-1;65078:50:0;65116:11;65078:33;64982:67;65096:14;65078:33;:17;:33;:::i;:::-;:37;:50;:37;:50;:::i;:::-;65062:66;;65141:43;65152:16;65170:13;65141:10;:43::i;:::-;64689:503;;;;;:::o;67535:277::-;67629:29;67673:30;67718;67783:21;:19;:21::i;:::-;67776:28;;;;;;67535:277;;;:::o;48830:342::-;48904:7;48924:19;48946:17;:15;:17::i;:::-;48924:39;-1:-1:-1;48978:16:0;;48974:191;;;49018:1;49011:8;;;;48974:191;49059:94;49141:11;49059:59;49095:22;:20;:22::i;62274:138::-;62352:5;;-1:-1:-1;;;;;62352:5:0;62338:10;:19;62330:44;;;;;-1:-1:-1;;;;;62330:44:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;62330:44:0;;;;;;;;;;;;;;;62385:19;62396:7;62385:10;:19::i;:::-;62274:138;:::o;68877:112::-;56540:29;;;;;;;;;;;;;;;;68919:7;;68946:35;;:33;:35::i;61207:806::-;61423:5;;-1:-1:-1;;;;;61423:5:0;61409:10;:19;61401:44;;;;;-1:-1:-1;;;;;61401:44:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;61401:44:0;;;;;;;;;;;;;;;61489:138;61601:24;61593:33;;61489:85;61548:24;61540:33;;61497:23;61489:32;;:50;;:85;;;;:::i;:::-;:103;:138;:103;:138;:::i;:::-;61480:5;:147;61458:213;;;;;-1:-1:-1;;;;;61458:213:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;56159:34;;;;;;;;;;;;;;;;61684:59;;61719:23;61684:11;:59::i;:::-;56251:35;;;;;;;;;;;;;;;;61754:61;;61790:24;61754:11;:61::i;:::-;56349:39;;;;;;;;;;;;;;;;61826:66;;61867:24;61826:11;:66::i;:::-;61910:95;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61207:806;;;:::o;60724:204::-;60806:5;;-1:-1:-1;;;;;60806:5:0;60792:10;:19;60784:44;;;;;-1:-1:-1;;;;;60784:44:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;60784:44:0;;;;;;;;;;;;;;;56076:26;;;;;;;;;;;;;;;;60839:42;;60865:15;60839:11;:42::i;:::-;60897:23;;;;;;;;;;;;;;;;;;;60724:204;:::o;60141:122::-;60220:35;60242:12;60220:21;:35::i;64580:101::-;64631:42;64653:19;64631:21;:42::i;41738:80::-;41796:14;;;;;;;;;;;;;;;;;41738:80;:::o;59476:114::-;59537:7;59564:18;59572:9;59564:7;:18::i;55597:58::-;55653:2;55597:58;:::o;47323:364::-;47465:10;47410:4;47454:22;;;:10;:22;;;;;;;;-1:-1:-1;;;;;47454:32:0;;;;;;;;;;47505:36;;;;47497:79;;;;;-1:-1:-1;;;;;47497:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;47587:70;47596:10;47608:8;47618:38;:16;47639;47618:38;:20;:38;:::i;47587:70::-;47675:4;47668:11;;47323:364;;;;;;:::o;55548:42::-;55588:2;55548:42;:::o;64158:414::-;37398:37;;;-1:-1:-1;;;;;;;;;;;37398:37:0;;;;;;;;;;;;37489;;:35;:37::i;:::-;37481:69;;;;;;;-1:-1:-1;;;;;37481:69:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;37481:69:0;;;;;;;;;;;;;;;64535:29;;;-1:-1:-1;;;;;64535:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;43551:160;43622:4;43639:42;43649:10;43661;43673:7;43639:9;:42::i;68606:158::-;56451:38;;;;;;;;;;;;;;;;68657:16;;68710:45;;:43;:45::i;70020:360::-;57214:42;;;-1:-1:-1;;;;;;;;;;;57214:42:0;;;;;;;;;;;;70066:27;;;;;;70177:49;;:47;:49::i;:::-;57578:39;;;-1:-1:-1;;;;;;;;;;;57578:39:0;;;;;;;;;;;;70155:71;;-1:-1:-1;70256:46:0;;:44;:46::i;:::-;57408:36;;;-1:-1:-1;;;;;;;;;;;57408:36:0;;;;;;;;;;;;70237:65;;-1:-1:-1;70329:43:0;;:41;:43::i;:::-;70313:59;;70020:360;;;:::o;63061:166::-;63153:5;;-1:-1:-1;;;;;63153:5:0;63139:10;:19;63131:44;;;;;-1:-1:-1;;;;;63131:44:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;63131:44:0;;;;;;;;;;;;;;;63186:33;63204:14;63186:17;:33::i;67356:99::-;67397:21;67438:9;:7;:9::i;47950:99::-;47997:7;48024:17;:15;:17::i;43983:137::-;-1:-1:-1;;;;;44084:18:0;;;44057:7;44084:18;;;:10;:18;;;;;;;;:28;;;;;;;;;;;;;43983:137::o;63640:332::-;63748:5;;-1:-1:-1;;;;;63748:5:0;63734:10;:19;63726:44;;;;;-1:-1:-1;;;;;63726:44:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;63726:44:0;;;;;;;;;;;;;;;57767;;;;;;;;;;;;;;;;63783:73;;63833:22;63783:73;:49;:73;:::i;:::-;63867:14;:12;:14::i;:::-;-1:-1:-1;;;;;63867:29:0;;:31;;;;;-1:-1:-1;;;63867:31:0;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63867:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;63916:48:0;;;;;;;;;;-1:-1:-1;63916:48:0;;;;;;;-1:-1:-1;63916:48:0;63640:332;:::o;59778:119::-;59837:52;56024:2;59837:21;:52::i;62655:146::-;62737:5;;-1:-1:-1;;;;;62737:5:0;62723:10;:19;62715:44;;;;;-1:-1:-1;;;;;62715:44:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;62715:44:0;;;;;;;;;;;;;;;62770:23;62783:9;62770:12;:23::i;65537:1742::-;65707:27;65886:24;66486:26;66750:18;67171:15;37489:37;37398;;;;-1:-1:-1;;;;;;;;;;;37398:37:0;;;;;;;;;;;;;;37489:35;;;;:37::i;:::-;37481:69;;;;;;;-1:-1:-1;;;;;37481:69:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;37481:69:0;;;;;;;;;;;;;;;65663:11;:9;:11::i;:::-;-1:-1:-1;;;;;65649:25:0;:10;:25;65641:53;;;;;-1:-1:-1;;;;;65641:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;57214:42;;;-1:-1:-1;;;;;;;;;;;57214:42:0;;;;;;;;;;;;65737:49;;:47;:49::i;:::-;65707:79;-1:-1:-1;65805:40:0;;;;65797:76;;;;;-1:-1:-1;;;;;65797:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;57578:39;;;-1:-1:-1;;;;;;;;;;;57578:39:0;;;;;;;;;;;;65913:46;;:44;:46::i;:::-;65886:73;-1:-1:-1;66409:37:0;;;;66401:74;;;;;-1:-1:-1;;;;;66401:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;66515:39;:17;66537:16;66515:39;:21;:39;:::i;:::-;57408:36;;;-1:-1:-1;;;;;;;;;;;57408:36:0;;;;;;;;;;;;66486:68;;-1:-1:-1;66771:87:0;;66814:43;;:41;:43::i;:::-;66772:36;:18;55755:8;66772:36;:22;:36;:::i;66771:87::-;57408:36;;;-1:-1:-1;;;;;;;;;;;57408:36:0;;;;;;;;;;;;66750:108;;-1:-1:-1;66979:57:0;;67021:14;66979:57;:41;:57;:::i;:::-;57578:39;;;-1:-1:-1;;;;;;;;;;;57578:39:0;;;;;;;;;;;;67047:63;;67092:17;67047:63;:44;:63;:::i;:::-;67144:10;67127:14;:27;67123:149;;;67189:30;:14;67208:10;67189:30;:18;:30;:::i;:::-;67171:48;;67234:26;67252:7;67234:17;:26::i;:::-;65537:1742;;;;;;;:::o;48133:111::-;48190:7;48217:19;48227:8;48217:9;:19::i;57820:33::-;;;-1:-1:-1;;;;;57820:33:0;;:::o;30882:130::-;30988:15;;30978:27::o;52226:939::-;37398:37;;;-1:-1:-1;;;;;;;;;;;37398:37:0;;;;;;;;;;;;52323:22;;37489:37;;:35;:37::i;:::-;37481:69;;;;;;;-1:-1:-1;;;;;37481:69:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;37481:69:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;52366:24:0;;;;52358:61;;;;;-1:-1:-1;;;;;52358:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52449:36;52471:13;52449:17;:15;:17::i;:36::-;41427:35;;;;;;;;;;;;;;;;52432:53;;-1:-1:-1;52496:55:0;;52432:53;52496:55;:39;:55;:::i;:::-;-1:-1:-1;;;;;52585:18:0;;:6;:18;;;;;;;;;;;:37;;52608:13;52585:37;:22;:37;:::i;:::-;-1:-1:-1;;;;;52564:18:0;;;:6;:18;;;;;;;;;;:58;;;;-1:-1:-1;52226:939:0;:::o;80685:229::-;80777:74;80819:31;80843:6;80819:19;:17;:19::i;:31::-;57022:36;;;;;;;;;;;;;;;;;80777:74;:41;:74;:::i;:::-;80869:37;;;;;;-1:-1:-1;;;;;80869:37:0;;;;;;;;;;;;;;;;;;;;;80685:229;;;:::o;72718:172::-;-1:-1:-1;;;;;72820:62:0;;72837:1;72820:62;72846:35;72867:13;72846:20;:35::i;:::-;72820:62;;;;;;;;;;;;;;;72718:172;;:::o;37966:125::-;37398:37;;;-1:-1:-1;;;;;;;;;;;37398:37:0;;;;;;;;;;;;37621;;:35;:37::i;:::-;37620:38;37612:69;;;;;-1:-1:-1;;;;;37612:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;37398:37;;;-1:-1:-1;;;;;;;;;;;37398:37:0;;;;;;;;;;;;38017:41;;38053:4;38017:41;:35;:41;:::i;:::-;38074:9;;;;;;;37966:125::o;37831:127::-;37398:37;;;-1:-1:-1;;;;;;;;;;;37398:37:0;;;;;;;;;;;;37489;;:35;:37::i;:::-;37481:69;;;;;;;-1:-1:-1;;;;;37481:69:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;37481:69:0;;;;;;;;;;;;;;;37398:37;;;-1:-1:-1;;;;;;;;;;;37398:37:0;;;;;;;;;;;;37883:42;;37919:5;37883:42;:35;:42;:::i;:::-;37941:9;;;;;;;37831:127::o;50243:341::-;37398:37;;;-1:-1:-1;;;;;;;;;;;37398:37:0;;;;;;;;;;;;37489;;:35;:37::i;:::-;37481:69;;;;;;;-1:-1:-1;;;;;37481:69:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;37481:69:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;50355:20:0;;;;50347:58;;;;;-1:-1:-1;;;;;50347:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50424:22:0;;;;50416:58;;;;;-1:-1:-1;;;;;50416:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50487:18:0;;;;;;;:10;:18;;;;;;;;:28;;;;;;;;;;;;;:38;;;50541:35;;;;;;;;;;;;;;;;;50243:341;;;:::o;83964:340::-;84019:7;84039:23;84095:21;84173:24;84065:19;:17;:19::i;:::-;57408:36;;;-1:-1:-1;;;;;;;;;;;57408:36:0;;;;;;;;;;;;84039:45;;-1:-1:-1;84119:43:0;;:41;:43::i;:::-;84095:67;;84200:22;:20;:22::i;:::-;84173:49;-1:-1:-1;84240:56:0;84173:49;84240:34;:15;84260:13;84240:34;:19;:34;:::i;:56::-;84233:63;;83964:340;;;;:::o;50667:126::-;41427:35;;;;;;;;;;;;;;;;50717:7;;50744:41;;:39;:41::i;26981:460::-;27041:7;;27285;;27281:48;;;27316:1;27309:8;;;;27281:48;-1:-1:-1;27353:7:0;;;27358:2;27353;:7;27379:6;;;;;;;27393:18;;;;;;;;;;;;;;;;;;27379:6;;;:12;27371:41;;;;-1:-1:-1;;;;;27371:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;27371:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27432:1:0;26981:460;-1:-1:-1;;;26981:460:0:o;27564:319::-;27660:14;;;;;;;;;;;;;;;;;27624:7;;;;27652:6;;;27644:31;;;;-1:-1:-1;;;;;27644:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;27644:31:0;;27761:2;27756;:7;;;;;;;;;27564:319;-1:-1:-1;;;;27564:319:0:o;49629:278::-;49722:25;49750:29;49771:7;49750:20;:29::i;:::-;49722:57;;49790:55;49806:7;49815:10;49827:17;49790:15;:55::i;:::-;49879:10;-1:-1:-1;;;;;49861:38:0;49870:7;-1:-1:-1;;;;;49861:38:0;;49891:7;49861:38;;;;;;;;;;;;;;;;;;49629:278;;;;:::o;28009:177::-;28107:19;;;;;;;;;;;;;;;;;28069:7;;;;28097:8;;;;28089:38;;;;-1:-1:-1;;;;;28089:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;28089:38:0;-1:-1:-1;;;28150:7:0;;;28009:177::o;28262:175::-;28389:18;;;;;;;;;;;;;;;;;28322:7;;28354;;;;28380;;;;28372:36;;;;-1:-1:-1;;;;;28372:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;82581:222:0;57022:36;;;;;;;;;;;;;;;;82633:7;;;;82672:43;;:41;:43::i;:::-;82653:62;-1:-1:-1;82741:4:0;82733:21;:33;-1:-1:-1;82733:33:0;82726:41;;;;82787:8;82581:222;-1:-1:-1;82581:222:0:o;50877:111::-;-1:-1:-1;;;;;50964:16:0;50937:7;50964:16;;;;;;;;;;;;50877:111::o;81818:393::-;81881:29;81912:30;81944;82017:35;56159:34;;;;;;;;;;;;;;;;;;;82017:12;:35::i;:::-;56251;;;;;;;;;;;;;;;;81992:60;;-1:-1:-1;82089:36:0;;:12;:36::i;:::-;56349:39;;;;;;;;;;;;;;;;82063:62;;-1:-1:-1;82162:41:0;;:12;:41::i;70852:107::-;56540:29;;;;;;;;;;;;;;;;70909:42;;70943:7;70909:42;:33;:42;:::i;81385:180::-;81474:5;81464:15;;;;;81456:50;;;;;-1:-1:-1;;;;;81456:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;81517:40;:5;81541:15;;;81517:40;:23;:40;:::i;:::-;81385:180;;:::o;73019:471::-;37398:37;;;-1:-1:-1;;;;;;;;;;;37398:37:0;;;;;;;;;;;;73107:16;;;;;;37489:37;;:35;:37::i;:::-;37481:69;;;;;;;-1:-1:-1;;;;;37481:69:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;37481:69:0;;;;;;;;;;;;;;;73126:19;:17;:19::i;:::-;73107:38;-1:-1:-1;55755:8:0;73160:24;;73156:327;;73223:22;:20;:22::i;:::-;73201:44;-1:-1:-1;73282:26:0;:8;55755;73282:26;:12;:26;:::i;:::-;73260:48;;73323:88;73341:69;73368:12;73354:11;:26;:55;;73397:12;73354:55;;;73383:11;73354:55;73341:12;:69::i;:::-;73323:17;:88::i;:::-;73459:11;73433:22;:20;:22::i;:::-;:37;73426:45;;;;73019:471;;;;:::o;71483:219::-;-1:-1:-1;;;;;71562:28:0;;;;71554:72;;;;;-1:-1:-1;;;;;71554:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;56824:36;;;;;;;;;;;;;;;;71637:57;;71679:14;71637:57;:41;:57;:::i;81639:102::-;56076:26;;;;;;;;;;;;;;;;81681:6;;81707:26;;:12;:26::i;31704:121::-;31794:22;;31792:26::o;71288:187::-;-1:-1:-1;;;;;71357:23:0;;;;71349:61;;;;;-1:-1:-1;;;;;71349:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;56734:31;;;;;;;;;;;;;;;;71421:46;;71457:9;71421:46;:35;:46;:::i;76703:3077::-;78386:16;78425:19;78911:30;78943;79011:23;79099:21;79301:36;79513:18;79613:16;78405:9;:7;:9::i;:::-;78386:28;;;-1:-1:-1;78462:186:0;78549:84;78605:27;78386:28;78618:13;78605:27;:12;:27;:::i;:::-;78549:33;78576:5;78549:22;:20;:22::i;:::-;:26;:33;:26;:33;:::i;:84::-;78462:50;78494:17;:15;:17::i;:::-;78462:27;:13;78480:8;78462:27;:17;:27;:::i;:186::-;78425:234;;78857:39;78877:4;78884:11;78857;:39::i;:::-;;78977:21;:19;:21::i;:::-;78909:89;;-1:-1:-1;78909:89:0;-1:-1:-1;79037:51:0;;-1:-1:-1;79082:5:0;79037:40;:11;:40;;;;:15;:40;:::i;:51::-;79011:77;;79123:18;:16;:18::i;:::-;79099:42;;79152:62;79176:4;79183:13;79198:15;79152;:62::i;:::-;79225:63;79257:13;79272:15;79225:31;:63::i;:::-;79340:107;79385:51;79430:5;79385:40;:11;:40;;;;:15;:40;:::i;:51::-;79340:30;:107::i;:::-;79301:146;-1:-1:-1;79534:66:0;79301:146;79534:32;:11;79550:15;79534:32;:15;:32;:::i;:66::-;79513:87;;79632:13;:11;:13::i;:::-;79613:32;;79656:52;79680:4;79687:8;79697:10;79656:15;:52::i;:::-;79719:53;79751:8;79761:10;79719:31;:53::i;:::-;76703:3077;;;;;;;;;;:::o;83326:509::-;57214:42;;;-1:-1:-1;;;;;;;;;;;57214:42:0;;;;;;;;;;;;83381:7;;;;;;;;83431:49;;:47;:49::i;:::-;57578:39;;;-1:-1:-1;;;;;;;;;;;57578:39:0;;;;;;;;;;;;83401:79;;-1:-1:-1;83518:46:0;;:44;:46::i;:::-;83491:73;-1:-1:-1;83650:39:0;;;;83643:47;;;;83731:41;:19;83755:16;83731:41;:23;:41;:::i;:::-;83701:71;-1:-1:-1;83790:37:0;83701:71;55755:8;83790:37;:23;:37;:::i;51334:555::-;37398:37;;;-1:-1:-1;;;;;;;;;;;37398:37:0;;;;;;;;;;;;51607:27;;37489:37;;:35;:37::i;:::-;37481:69;;;;;;;-1:-1:-1;;;;;37481:69:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;37481:69:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;51462:21:0;;;;51454:64;;;;;-1:-1:-1;;;;;51454:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51537:24:0;;;;51529:65;;;;;-1:-1:-1;;;;;51529:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;51637:15:0;;:6;:15;;;;;;;;;;;51671:36;;;;51663:80;;;;;-1:-1:-1;;;;;51663:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;51774:38;:19;51798:13;51774:38;:23;:38;:::i;:::-;-1:-1:-1;;;;;51756:15:0;;;:6;:15;;;;;;;;;;;:56;;;;51844:18;;;;;;;:37;;51867:13;51844:37;:22;:37;:::i;:::-;-1:-1:-1;;;;;51823:18:0;;;:6;:18;;;;;;;;;;:58;;;;-1:-1:-1;;;51334:555:0:o;82291:180::-;82351:6;;82382:25;:5;:23;:25::i;:::-;82370:37;-1:-1:-1;82430:5:0;82425:10;;;82418:18;;;31575:121;31665:22;;31663:26::o;82901:136::-;82956:7;82983:46;83009:19;:17;:19::i;:::-;82991:4;82983:21;;:46;:25;:46;:::i;73669:1120::-;73731:7;73752:20;73774:23;74130:15;74304:9;74352:19;74446:22;73801:14;:12;:14::i;:::-;-1:-1:-1;;;;;73801:36:0;;73838:12;73801:50;;;;;-1:-1:-1;;;73801:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73801:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73801:50:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;73801:50:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;;;5:11;;2:2;;;29:1;26;19:12;2:2;73801:50:0;;;;;;20:11:-1;15:3;12:20;9:2;;;45:1;42;35:12;9:2;64:21;;126:4;117:14;;142:31;;;139:2;;;186:1;183;176:12;139:2;218:10;;268:11;251:29;;293:43;;;290:58;-1:-1;239:118;236:2;;;370:1;367;360:12;236:2;0:382;;73801:50:0;;;;;;;20:11:-1;15:3;12:20;9:2;;;45:1;42;35:12;9:2;64:21;;126:4;117:14;;142:31;;;139:2;;;186:1;183;176:12;139:2;218:10;;268:11;251:29;;293:43;;;290:58;-1:-1;239:118;236:2;;;370:1;367;360:12;236:2;-1:-1;;73868:14:0;;73751:100;;-1:-1:-1;73801:50:0;-1:-1:-1;;;73868:19:0;;73864:60;;-1:-1:-1;73864:60:0;;73911:1;73904:8;;;;73864:60;73944:14;;:33;;55588:2;73944:33;:18;:33;:::i;:::-;:38;73936:84;;;;;-1:-1:-1;;;;;73936:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74039:17;;:39;;55705:2;74039:39;:21;:39;:::i;:::-;:44;74031:86;;;;;-1:-1:-1;;;;;74031:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;74148:14;;:33;;55588:2;74148:33;:18;:33;:::i;:::-;74211:17;;74130:51;;-1:-1:-1;74211:39:0;;55705:2;74211:39;:21;:39;:::i;:::-;74200:50;;74192:94;;;;;-1:-1:-1;;;;;74192:94:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;74316:1;74304:13;;74299:290;74323:7;74319:1;:11;74299:290;;;74374:57;74389:7;55588:2;74398:1;:17;55588:2;74374:14;:57::i;:::-;74352:79;;74471:66;74486:10;55705:2;74498:1;:20;55705:2;74471:14;:66::i;:::-;74446:91;;74552:25;74559:6;74567:9;74552:6;:25::i;:::-;74332:3;;;;;74299:290;;;57214:42;;;-1:-1:-1;;;;;;;;;;;57214:42:0;;;;;;;;;;;;74601:135;;74663:62;;74717:7;;74663:49;;:47;:49::i;:62::-;57214:42;;;-1:-1:-1;;;;;;;;;;;57214:42:0;;;;;;;;;;;;;74601:135;:47;:135;:::i;:::-;74756:25;:7;55755:8;74756:25;:11;:25;:::i;:::-;74749:32;;73669:1120;;;;;;;;;;:::o;81082:222::-;57022:36;;;;;;;;;;;;;;;;81146:113;;81202:56;;81250:7;;81202:43;;:41;:43::i;81146:113::-;81277:19;;;;;;;;;;;;;;;;;81082:222;:::o;79788:675::-;79875:19;79908:27;79937:23;80121:11;79964:14;:12;:14::i;:::-;-1:-1:-1;;;;;79964:37:0;;80002:19;79964:58;;;;;-1:-1:-1;;;79964:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;79964:58:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;79964:58:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;79964:58:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;;;5:11;;2:2;;;29:1;26;19:12;2:2;79964:58:0;;;;;;20:11:-1;15:3;12:20;9:2;;;45:1;42;35:12;9:2;64:21;;126:4;117:14;;142:31;;;139:2;;;186:1;183;176:12;139:2;224:3;218:10;339:9;333:2;319:12;315:21;297:16;293:44;290:59;268:11;254:12;251:29;239:119;236:2;;;371:1;368;361:12;236:2;0:383;;79964:58:0;;;;;;;20:11:-1;15:3;12:20;9:2;;;45:1;42;35:12;9:2;64:21;;126:4;117:14;;142:31;;;139:2;;;186:1;183;176:12;139:2;224:3;218:10;339:9;333:2;319:12;315:21;297:16;293:44;290:59;268:11;254:12;251:29;239:119;236:2;;;371:1;368;361:12;236:2;0:383;;79964:58:0;;;;;;79907:115;;;;80063:6;:13;80042:10;:17;:34;80035:42;;;;;;-1:-1:-1;80104:1:0;;-1:-1:-1;80104:1:0;80116:340;80144:10;:17;80138:3;:23;80116:340;;;80185:126;80227:4;80251:10;80262:3;80251:15;;;;;;;;;;;;;;;;;;80285:6;80292:3;80285:11;;;;;;;;;;;;;;;;;;80185:15;:126::i;:::-;80326:61;80358:10;80369:3;80358:15;;;;;;;;;;;;;;;;;;80375:6;80382:3;80375:11;;;;;;;;;;;;;;;;;;80326:31;:61::i;:::-;80416:28;80432:6;80439:3;80432:11;;;;;;;;;;;;;;;;;;;80416;;:28;:15;:28;:::i;:::-;80402:42;-1:-1:-1;80163:5:0;;80116:340;;28585:140;28679:14;;;;;;;;;;;;;;;;;28643:7;;28671:6;;;28663:31;;;;-1:-1:-1;;;;;28663:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;28663:31:0;;28716:1;28712;:5;;;;;;;;;28585:140;-1:-1:-1;;;28585:140:0:o;9381:2520::-;9461:5;9536:22;9514:7;9505:6;:16;9487:6;:13;:35;;9479:44;;;;;;;;9602:15;;9631:2005;;;;11780:4;11774:11;11761:24;;11833:4;11822:9;11818:20;11812:4;11805:34;9595:2259;;9631:2005;9816:4;9810:11;9797:24;;10485:2;10476:7;10472:16;10873:9;10866:17;10860:4;10856:28;10844:9;10833;10829:25;10825:60;10922:7;10918:2;10914:16;11179:6;11165:9;11158:17;11152:4;11148:28;11136:9;11128:6;11124:22;11120:57;11116:70;10950:434;11213:3;11209:2;11206:11;10950:434;;;11355:9;;11344:21;;11255:4;11247:13;;;;11288;10950:434;;;-1:-1:-1;;11404:26:0;;;11616:2;11599:11;-1:-1:-1;;11595:25:0;11589:4;11582:39;-1:-1:-1;9595:2259:0;-1:-1:-1;11884:9:0;9381:2520;-1:-1:-1;;;;9381:2520:0:o;74982:1515::-;75065:29;75214:13;75360:21;75619:18;75674:21;75925:23;76197:21;75097:26;:24;:26::i;:::-;75065:58;-1:-1:-1;75142:26:0;;;75134:67;;;;;-1:-1:-1;;;;;75134:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;55755:8;;-1:-1:-1;75384:30:0;55755:8;55820:14;75384:30;:9;:30;:::i;:::-;75360:54;-1:-1:-1;75474:5:0;75432:38;75360:54;55820:14;75432:38;:17;:38;:::i;:::-;:47;75425:55;;;;75640:23;75647:15;75654:7;75647:6;:15::i;:::-;75640:23;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;75640:23:0;;;;;;;-1:-1:-1;263:2;;-1:-1;;75640:23:0;;;;-1:-1:-1;75640:23:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75640:23:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;75640:23:0;;-1:-1:-1;75698:214:0;;75761:33;75776:10;75788:1;75791:2;75761:14;:33::i;:::-;75754:41;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;75754:41:0;;;;;;;-1:-1:-1;263:2;;-1:-1;;75754:41:0;;;;-1:-1:-1;75754:41:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75754:41:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;75754:41:0;75814:72;75821:64;75828:56;75843:10;75855:2;75859:24;55705:2;75855;75859:24;:20;:24;:::i;:::-;75828:14;:56::i;:::-;75821:6;:64::i;:::-;75814:72;;;;;;;;;;;;;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;75814:72:0;;;;;;;-1:-1:-1;263:2;;-1:-1;;75814:72:0;;;;-1:-1:-1;75814:72:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75814:72:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;75814:72:0;75719:182;;;75814:72;75719:182;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;75719:182:0;;;;;;;;75698:214;;75719:182;;;;;;75698:214;;;;75719:182;75698:214;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;75698:214:0;;;;;;;-1:-1:-1;263:2;;-1:-1;;75698:214:0;;;;-1:-1:-1;75698:214:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75698:214:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;75698:214:0;76014:51;;;75698:214;76014:51;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;76014:51:0;;;;;;;;76007:59;;75698:214;;-1:-1:-1;75951:233:0;;;;76014:51;;;76007:59;;;;;76014:51;76007:59;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;76007:59:0;;;;;;;-1:-1:-1;263:2;;-1:-1;;76007:59:0;;;;-1:-1:-1;76007:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;76007:59:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;76007:59:0;76085:73;76109:32;76127:13;76109:17;:32::i;:::-;76092:65;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;76092:65:0;;;;;;;;76085:73;;76092:65;;;;76085:73;;;;;76092:65;76085:73;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;76085:73:0;;;;;;;-1:-1:-1;263:2;;-1:-1;;76085:73:0;;;;-1:-1:-1;76085:73:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;76085:73:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;76085:73:0;75972:201;;;76085:73;75972:201;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;75972:201:0;;;;;;;;75951:233;;75972:201;;;;;;75951:233;;;;75972:201;75951:233;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;75951:233:0;;;;;;;-1:-1:-1;263:2;;-1:-1;;75951:233:0;;;;-1:-1:-1;75951:233:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75951:233:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;75951:233:0;;-1:-1:-1;76221:32:0;76229:4;76221:21;76247:5;76221:32;:25;:32;:::i;:::-;76197:56;;76266:20;:18;:20::i;:::-;-1:-1:-1;;;;;76266:28:0;;76301:5;76322:7;76348:21;76331:39;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;76331:39:0;;;76372:10;76384:15;76266:134;;;;;-1:-1:-1;;;76266:134:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;76266:134:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;76266:134:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;76266:134:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;76266:134:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;76266:134:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;76266:134:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;;;76427:4:0;76419:21;:38;;;-1:-1:-1;76411:78:0;;;;;-1:-1:-1;;;;;76411:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;74982:1515;;;;;;;;;:::o;84455:475::-;84511:5;84645:19;84556:2;84543;:9;:15;;:34;;;;;84575:2;84562;:9;:15;;84543:34;84536:42;;;;;;84599:2;:9;84593:2;:15;84589:43;;;84630:2;84623:9;;;;84589:43;84667:13;;;84677:2;84667:13;;;;;;;;;;;;;17:15:-1;;105:10;84667:13:0;88:34:-1;136:17;;-1:-1;84667:13:0;84645:35;;84728:1;84721:4;84713:6;84709:17;84702:28;84754:2;:9;84748:2;:15;84744:178;;;84785:27;84801:2;84805:6;84785:15;:27::i;84744:178::-;84848:74;84864:2;84868:53;84883:6;84891:1;84894:26;84910:2;:9;84902:2;84894:15;;:26;;;;:::i;84868:53::-;84848:15;:74::i;85125:381::-;85191:14;85260:6;85191:14;85277:134;85301:1;85297;:5;85277:134;;;85334:11;;;;85363:4;85350:17;;85333:35;;85383:16;;;;85304:3;;85277:134;;;85430:15;;85423:23;;;;-1:-1:-1;;85479:19:0;;;85125:381;-1:-1:-1;85125:381:0:o;148:2968::-;236:5;254:22;464:4;458:11;445:24;;625:9;619:16;667:6;656:9;649:25;914:4;903:9;899:20;1066:6;1062:2;1058:15;1265:4;1254:9;1250:20;1089:537;1293:3;1289:2;1286:11;1089:537;;;1601:9;;1590:21;;1402:4;1394:13;;;;1431;1089:537;;;-1:-1:-1;1842:17:0;;1903:16;;1891:29;;1873:48;;1842:17;-1:-1:-1;2069:3:0;-1:-1:-1;2209:15:0;;;2289:4;2273:21;;2240:228;2317:3;2313:2;2310:11;2240:228;;;2443:9;;2432:21;;2355:4;2347:13;;;;2384;2240:228;;;-1:-1:-1;2966:16:0;;2954:29;;;;2947:37;2938:47;;;;3011:2;2934:56;-1:-1:-1;;2914:154:0;2908:4;2901:168;3099:9;148:2968;-1:-1:-1;;;148:2968:0:o
Swarm Source
bzzr://901141453bed940aab639f2821e61b7adb872d37a602b2f7d3b2bb33946e5ad7
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.