Contract 0xd40EefCFaB888C9159a61221def03bF77773FC19 2

Contract Overview

Balance:
563.436386569880361463 Ether
Txn Hash
Method
Block
From
To
Value
0x94917a599f1993f9ebb6ad1f26d14c1f79c3d13b3df595dffbf01108522ad8a4Approve129908072022-09-15 12:31:2413 days 18 hrs ago0x14e5f8f2246210efbb05fb8660b4be6d7045fb70 IN  0xd40eefcfab888c9159a61221def03bf77773fc190 Ether0.00007351 1.5
0x4b2229bbad61bad0cc710dc195d971a4c5434d85c882d3e6b86814bfeab35b09Submit129748662022-09-12 17:20:0016 days 13 hrs ago0x27e2119bc9fbca050df65ddd97cb9bd14676a08b IN  0xd40eefcfab888c9159a61221def03bf77773fc191 wei0.00007381 1
0x583aed530280187d58a5401eaf2b226deb0e4aa1ed39d73818baabd0fd3fc6f9Approve129423492022-09-07 4:13:1222 days 2 hrs ago0x36e2063455d476ac7ed3840df578a63e9cc39ced IN  0xd40eefcfab888c9159a61221def03bf77773fc190 Ether0.00007351 1.5
0x9daadbcd302e95a85ee92c82e08c963de7383146cd09cb933cb3fdd109d0831aApprove129389232022-09-06 14:26:1222 days 16 hrs ago0x36e2063455d476ac7ed3840df578a63e9cc39ced IN  0xd40eefcfab888c9159a61221def03bf77773fc190 Ether0.00007351 1.5
0x5d7ed49cae696f8c68f836919de50603bbfda915db24bd3d27deefa481de7ce1Transfer129389202022-09-06 14:25:0022 days 16 hrs ago0x36e2063455d476ac7ed3840df578a63e9cc39ced IN  0xd40eefcfab888c9159a61221def03bf77773fc190.1 Ether0.00008309 1.5
0xcb9e7b76ee7f8ee427f5c7eb64e447e62297e54cbe446701442bb8fac3c158b5Transfer129389152022-09-06 14:23:4822 days 16 hrs ago0x36e2063455d476ac7ed3840df578a63e9cc39ced IN  0xd40eefcfab888c9159a61221def03bf77773fc191 Ether0.00010874 1.5
0x34d51564dd4e1837b1a6d89d707f1f130ea87c4b0ec6f71d4360c6bd6a4a85e0Submit129317372022-09-05 9:35:0023 days 21 hrs ago0x9d20333a42701346820c58a12f404a15452581c3 IN  0xd40eefcfab888c9159a61221def03bf77773fc190.0000001 Ether0.00005671 1
0x6c3b4d7819f0dfce896591d0ea21aeb6987c60fb5cae26cc0a5ba6d37f0f4870Submit129317332022-09-05 9:34:1223 days 21 hrs ago0x9d20333a42701346820c58a12f404a15452581c3 IN  0xd40eefcfab888c9159a61221def03bf77773fc190.00001 Ether0.00005671 1
0x69d0308ada8bbaf690e1a6f4901bf59327412a274def7ac13250a07ce17b8809Submit129317292022-09-05 9:33:2423 days 21 hrs ago0x9d20333a42701346820c58a12f404a15452581c3 IN  0xd40eefcfab888c9159a61221def03bf77773fc190.0001 Ether0.00005671 1
0xba7edc39f5c58c9251af7325c7786ac9a71d55268de42f132866ea6cf0ecda4aSubmit129002042022-08-31 7:00:1228 days 23 hrs ago0x9d20333a42701346820c58a12f404a15452581c3 IN  0xd40eefcfab888c9159a61221def03bf77773fc190.0001 Ether0.00005671 1
0x9aa71eeb7f57f7a7a7ffca55a18b1fbebae4f9d66e7e0f0b1d60f794bd37bc6eTransfer129001892022-08-31 6:56:4828 days 23 hrs ago0x6a6b7c7da17b48f1b2ea481455d17b1c8b7d2d28 IN  0xd40eefcfab888c9159a61221def03bf77773fc191 Ether0.0007755514
0x8c9a77815cd311fbe8b2f5fe442b8db93d5aa9ed48a2add060080e2aef375970Transfer128940122022-08-30 8:22:3629 days 22 hrs ago0x6a6b7c7da17b48f1b2ea481455d17b1c8b7d2d28 IN  0xd40eefcfab888c9159a61221def03bf77773fc191 Ether0.0009424613
0x2535ebb7642b6b496c6eb79212c4e76b3df311eb8803a1757a4fdb2e3acc51e3Submit128935622022-08-30 6:46:0030 days 8 mins ago0x9d20333a42701346820c58a12f404a15452581c3 IN  0xd40eefcfab888c9159a61221def03bf77773fc190.001 Ether0.00007381 1
0xbb8e3dce815bf18af930324cc3871749246d27b4b1aeef3c5de4063e543dfe97Approve127949692022-08-15 17:13:2444 days 13 hrs ago0xbb7e929741621944e1d38cf1c8654d8cf34943fc IN  0xd40eefcfab888c9159a61221def03bf77773fc190 Ether0.00007351 1.5
0xc1bf367d2cbd08636401cb4bb9b170a236b3eefb7e950e232b52541ef8339c78Submit127949582022-08-15 17:11:1244 days 13 hrs ago0xbb7e929741621944e1d38cf1c8654d8cf34943fc IN  0xd40eefcfab888c9159a61221def03bf77773fc191.01368784 Ether0.00011035 1.5
0xdf96e9e97d3d15c3ea5c3165f336e3a5ba0a3df2b93bca67842e9d00921f2f8cSubmit126053062022-07-16 15:14:3674 days 15 hrs ago0xdfec4604b46c28e14e5f2530d71604a64b1d8a8d IN  0xd40eefcfab888c9159a61221def03bf77773fc191 Ether0.0000847 1.5
0x301aa112d0b3f9301e85f39707a8026d6859d0d10e603a59316b488bf176835dSubmit126053042022-07-16 15:14:1274 days 15 hrs ago0xdfec4604b46c28e14e5f2530d71604a64b1d8a8d IN  0xd40eefcfab888c9159a61221def03bf77773fc191 Ether0.00011035 1.5
0x77c6574dd55cdd0e5c63218b86d0bbb7b38912de9801caa2e746bb918c73eebaTransfer125574912022-07-09 11:51:1281 days 19 hrs ago0xa145836bfcbd7bc7b23c0ca132119bcd98cf7e29 IN  0xd40eefcfab888c9159a61221def03bf77773fc192 Ether0.00010874 1.5
0x6d6f1777edae5224bc269dd8c9900787cfdc7bc35b34eaa89a78a310f36df889Approve125520452022-07-08 16:03:4882 days 14 hrs ago0x2b5303771e86b5c1476f35e36bf8a914212ee553 IN  0xd40eefcfab888c9159a61221def03bf77773fc190 Ether0.00007304 1.5
0x02394bb41997838da97b401ca3112e35c44df0b4ff4623d1d0cfa80ee0efb7eeApprove125520412022-07-08 16:03:0082 days 14 hrs ago0x206739f22f107d63426dfc1bd3870b083fcc1367 IN  0xd40eefcfab888c9159a61221def03bf77773fc190 Ether0.00007304 1.5
0x8337026287ad46e5fbddf0d222f8aafc1a4270326e3cb6dc4c9ce8b2339e8aefApprove125231482022-07-04 11:00:3686 days 19 hrs ago0x2b5303771e86b5c1476f35e36bf8a914212ee553 IN  0xd40eefcfab888c9159a61221def03bf77773fc190 Ether0.00007304 1.5
0x01b8eac3313936989b2b41a6e9819e4a47a8d4dff0a5b7799357279748fd26adSubmit123833052022-06-13 6:42:12108 days 12 mins ago0x548487537a9393ca610f62dabb89c1df7706f04d IN  0xd40eefcfab888c9159a61221def03bf77773fc191 Ether0.00011035 1.5
0x610ee81c85b9ddbb43e4a39969038e8a16fe474962036aa3597e6fd69c7487e4Approve122949992022-05-24 18:22:20127 days 12 hrs ago0x62a3d8a878beef2ba024bbc26c5be9d2ee4dde7e IN  0xd40eefcfab888c9159a61221def03bf77773fc190 Ether0.00023946 4.91770247
0xe1f21952a1e293f9e00b07be64e8503ba5ce01b9050c1304037e5d349cbe145dSubmit122799632022-05-19 16:01:27132 days 14 hrs ago0x8bd14da4570916c9a90e20d9ab01bdf5223157da IN  0xd40eefcfab888c9159a61221def03bf77773fc190.01 Ether0.00044089 7.80751028
0xdcdd869fae08a6f0ae0d0f55dd81ce6a40ca25c2953ca66e58d030a5ccc33333Submit122600862022-05-12 23:35:18139 days 7 hrs ago0x2b1cfe8d8df70b711649f728de5d5af6a921fab5 IN  0xd40eefcfab888c9159a61221def03bf77773fc191 Ether0.0000847 1.5
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x18b76adf3f6a60c4e0f56c1ff282c84105c5a97d3dcd18ef19f3df197025d2fb129423742022-09-07 4:18:4822 days 2 hrs ago 0x46fd0c431d0041fa8af97d5ffa28869be6a266d2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x18b76adf3f6a60c4e0f56c1ff282c84105c5a97d3dcd18ef19f3df197025d2fb129423742022-09-07 4:18:4822 days 2 hrs ago 0x46fd0c431d0041fa8af97d5ffa28869be6a266d2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0xdb33d425dac7e47f20bcf9b53b1cec4efad76618ddcd87c5fc581d8f27fd377f129423642022-09-07 4:16:1222 days 2 hrs ago 0x46fd0c431d0041fa8af97d5ffa28869be6a266d2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0xdb33d425dac7e47f20bcf9b53b1cec4efad76618ddcd87c5fc581d8f27fd377f129423642022-09-07 4:16:1222 days 2 hrs ago 0x46fd0c431d0041fa8af97d5ffa28869be6a266d2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x458961bf27cff53c3205c6d502f7adf0f261ed96c2e52a5a7e5c1d583cd57728129423592022-09-07 4:15:1222 days 2 hrs ago 0x46fd0c431d0041fa8af97d5ffa28869be6a266d2 0xd40eefcfab888c9159a61221def03bf77773fc190.1 Ether
0xc8da366b0da2d920d5582b5442a2368534452f14a07b81a4c6456fba5be94fd7129423562022-09-07 4:14:3622 days 2 hrs ago 0x46fd0c431d0041fa8af97d5ffa28869be6a266d2 0xd40eefcfab888c9159a61221def03bf77773fc190.1 Ether
0xecaa0720e2008805368eac7ecaf1728ad08c05c1f84c3b8c87b3b024dee4c1a2129423492022-09-07 4:13:1222 days 2 hrs ago 0x46fd0c431d0041fa8af97d5ffa28869be6a266d2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x292c0752eb7925eafc202e03a841645c756de754cefe8d08a1fdf15fb71ae85c129423322022-09-07 4:09:0022 days 2 hrs ago 0x4266924fb6c12415fc2dd3536d1dbf02fff43da2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x292c0752eb7925eafc202e03a841645c756de754cefe8d08a1fdf15fb71ae85c129423322022-09-07 4:09:0022 days 2 hrs ago 0x4266924fb6c12415fc2dd3536d1dbf02fff43da2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x89a7572912335381b796744166d93791875718cd35ceafbd23a5ef3c8cba4bcb129423312022-09-07 4:08:4822 days 2 hrs ago 0x4266924fb6c12415fc2dd3536d1dbf02fff43da2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x89a7572912335381b796744166d93791875718cd35ceafbd23a5ef3c8cba4bcb129423312022-09-07 4:08:4822 days 2 hrs ago 0x4266924fb6c12415fc2dd3536d1dbf02fff43da2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x99dfe06f9fb3b503d82032e627f31ae98480fd609b2c3ecce59042b9b295620f129423272022-09-07 4:07:2422 days 2 hrs ago 0x4266924fb6c12415fc2dd3536d1dbf02fff43da2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x5aeeece6e3f2b01cb06d4818f321030192c46a25d73ad671e13f823d9d9617af129423172022-09-07 4:05:0022 days 2 hrs ago 0x4266924fb6c12415fc2dd3536d1dbf02fff43da2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x757a2e97458f90c167e820d10e2e28e21ba2e6be3229d8e385aab80975c5f5a8129423032022-09-07 4:02:1222 days 2 hrs ago 0x4266924fb6c12415fc2dd3536d1dbf02fff43da2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x757a2e97458f90c167e820d10e2e28e21ba2e6be3229d8e385aab80975c5f5a8129423032022-09-07 4:02:1222 days 2 hrs ago 0x4266924fb6c12415fc2dd3536d1dbf02fff43da2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x867e74a125c717babdb17eee896f9e34658d8ad4e4187dba652c7f1dd0b11a65129423002022-09-07 4:01:2422 days 2 hrs ago 0x4266924fb6c12415fc2dd3536d1dbf02fff43da2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x867e74a125c717babdb17eee896f9e34658d8ad4e4187dba652c7f1dd0b11a65129423002022-09-07 4:01:2422 days 2 hrs ago 0x4266924fb6c12415fc2dd3536d1dbf02fff43da2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0xeecb97b3b6f95b30a89e827cd4794380c042eab794fbfae96f25a617d9ff86c6129422942022-09-07 3:59:3622 days 2 hrs ago 0x4266924fb6c12415fc2dd3536d1dbf02fff43da2 0xd40eefcfab888c9159a61221def03bf77773fc190.1 Ether
0x2974a120729162b69be643b2d3caa833bd7dd20e70c0602a8e06a2c0f3ba7a84129422882022-09-07 3:58:2422 days 2 hrs ago 0x4266924fb6c12415fc2dd3536d1dbf02fff43da2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x2974a120729162b69be643b2d3caa833bd7dd20e70c0602a8e06a2c0f3ba7a84129422882022-09-07 3:58:2422 days 2 hrs ago 0x4266924fb6c12415fc2dd3536d1dbf02fff43da2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x2974a120729162b69be643b2d3caa833bd7dd20e70c0602a8e06a2c0f3ba7a84129422882022-09-07 3:58:2422 days 2 hrs ago 0x4266924fb6c12415fc2dd3536d1dbf02fff43da2 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0xcf06864129d8711f139c282d6224537c6d72f6f88a5fa8a43e29fbcff455e260129422802022-09-07 3:55:4822 days 2 hrs ago 0x2a0cfcd9823595e3ec7652144a6fc13f5d2ba2e6 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x22040194da5a3dcf71b9626a657c6728a952c0282f93f90bd87638a9c88c1948129422792022-09-07 3:55:3622 days 2 hrs ago 0x2a0cfcd9823595e3ec7652144a6fc13f5d2ba2e6 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x6d965d50231234619aed7f4af768aa681a2f64e43dc2bc92d1d7ab24d7f3948c129422642022-09-07 3:52:3622 days 3 hrs ago 0x2a0cfcd9823595e3ec7652144a6fc13f5d2ba2e6 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
0x6d965d50231234619aed7f4af768aa681a2f64e43dc2bc92d1d7ab24d7f3948c129422642022-09-07 3:52:3622 days 3 hrs ago 0x2a0cfcd9823595e3ec7652144a6fc13f5d2ba2e6 0xd40eefcfab888c9159a61221def03bf77773fc190 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Lido

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license

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);
    }
}

Contract ABI

[{"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"}]

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
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.