Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0xb1029Ac2Be4e08516697093e2AFeC435057f3511
Balance 0 ETH
Nonce 1
Code Size 9178 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

9178 bytes
0x608060405234801561001057600080fd5b50600436106100be5760003560e01c8063aea4e49e11610076578063de9b771f1161005b578063de9b771f146101ba578063ee0eb4a1146101da578063f953cec7146101e257600080fd5b8063aea4e49e14610187578063c0857ba01461019a57600080fd5b8063607f2d42116100a7578063607f2d4214610105578063972c4928146101385780639c14b3a81461017d57600080fd5b80630e387de6146100c35780632c4e722e146100fd575b600080fd5b6100ea7f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681565b6040519081526020015b60405180910390f35b6100ea6101f5565b610128610113366004611d57565b60036020526000908152604090205460ff1681565b60405190151581526020016100f4565b6002546101589073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f4565b6101856103e1565b005b610185610195366004611d92565b610488565b6001546101589073ffffffffffffffffffffffffffffffffffffffff1681565b6000546101589073ffffffffffffffffffffffffffffffffffffffff1681565b61012861057a565b6101856101f0366004611e73565b61058e565b6040517f21f8a7210000000000000000000000000000000000000000000000000000000081527f7630e125f1c009e5fc974f6dae77c6d5b1802979b36e6d7145463c21782af01e6004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000001d8f8f00cfa6758d7be78336684788fb0ee0fa4616906321f8a72190602401602060405180830381865afa1580156102a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c89190611ef3565b905060008173ffffffffffffffffffffffffffffffffffffffff1663c4c8d0ad6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610317573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061033b9190611f10565b90508060000361034e5760009250505090565b808273ffffffffffffffffffffffffffffffffffffffff1663964d042c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561039a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103be9190611f10565b6103d090670de0b6b3a7640000611f58565b6103da9190611fc4565b9250505090565b6103e96101f5565b60048190556040516000916104049160240190815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f69ea1771000000000000000000000000000000000000000000000000000000001790529050610485816105a7565b50565b60025473ffffffffffffffffffffffffffffffffffffffff1615610533576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f467842617365526f6f7454756e6e656c3a204348494c445f54554e4e454c5f4160448201527f4c52454144595f5345540000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006004546105876101f5565b1415905090565b600061059982610638565b90506105a3600080fd5b5050565b6000546002546040517fb472047700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9283169263b472047792610603929116908590600401612008565b600060405180830381600087803b15801561061d57600080fd5b505af1158015610631573d6000803e3d6000fd5b5050505050565b6060600061064583610a19565b9050600061065282610a78565b9050600061065f83610aa7565b905060008161066d84610ad0565b61067686610cbe565b60405160200161068893929190612076565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600390935291205490915060ff161561075d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4678526f6f7454756e6e656c3a20455849545f414c52454144595f50524f434560448201527f5353454400000000000000000000000000000000000000000000000000000000606482015260840161052a565b600081815260036020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561079d85610cda565b905060006107aa82610e24565b90506107b581610eb4565b60025473ffffffffffffffffffffffffffffffffffffffff90811691161461085f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4678526f6f7454756e6e656c3a20494e56414c49445f46585f4348494c445f5460448201527f554e4e454c000000000000000000000000000000000000000000000000000000606482015260840161052a565b600061086a87610edd565b905061088a61087a846020015190565b876108848a610ef9565b84610f15565b610916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4678526f6f7454756e6e656c3a20494e56414c49445f524543454950545f505260448201527f4f4f460000000000000000000000000000000000000000000000000000000000606482015260840161052a565b61094485610923896111c8565b61092c8a6111e4565b846109368c611200565b61093f8d61121c565b611238565b600061094f83611398565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b0366109856109808360006113d4565b61140c565b146109ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f5349474e415455524500604482015260640161052a565b60006109f784611487565b806020019051810190610a0a91906120a3565b9b9a5050505050505050505050565b6040805160208101909152606081526000610a63610a5e8460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b6114a3565b60408051602081019091529081529392505050565b6060610aa18260000151600881518110610a9457610a9461211a565b60200260200101516115b9565b92915050565b6000610aa18260000151600281518110610ac357610ac361211a565b602002602001015161140c565b60408051602081019091526000815281516060919015610aa157600080610af8600086611656565b60f81c90506001811480610b0f57508060ff166003145b15610bcf57600185516002610b249190611f58565b610b2e9190612149565b67ffffffffffffffff811115610b4657610b46611daf565b6040519080825280601f01601f191660200182016040528015610b70576020820181803683370190505b5092506000610b80600187611656565b90508084600081518110610b9657610b9661211a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001925050610c33565b600285516002610bdf9190611f58565b610be99190612149565b67ffffffffffffffff811115610c0157610c01611daf565b6040519080825280601f01601f191660200182016040528015610c2b576020820181803683370190505b509250600091505b60ff82165b8351811015610cb557610c62610c5160ff851683612149565b610c5c906002612160565b87611656565b848281518110610c7457610c7461211a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535080610cad81612178565b915050610c38565b50505092915050565b6000610aa18260000151600981518110610ac357610ac361211a565b610cfe60405180606001604052806060815260200160608152602001600081525090565b610d188260000151600681518110610a9457610a9461211a565b602082810182905260408051808201825260008082529083015280518082019091528251815291810190820152610d4e816116d7565b15610d6357610d5c816114a3565b8252610e10565b60208201518051600090610d7990600190612149565b67ffffffffffffffff811115610d9157610d91611daf565b6040519080825280601f01601f191660200182016040528015610dbb576020820181803683370190505b509050600080836021019150826020019050610dd982828551611712565b604080518082018252600080825260209182015281518083019092528451825280850190820152610e09906114a3565b8652505050505b610e1983610cbe565b604083015250919050565b604080516080810182526000918101828152606080830193909352815260208101919091526000610e728360000151600381518110610e6557610e6561211a565b60200260200101516114a3565b836040015181518110610e8757610e8761211a565b602002602001015190506040518060400160405280828152602001610eab836114a3565b90529392505050565b6000610aa18260200151600081518110610ed057610ed061211a565b602002602001015161179d565b6000610aa18260000151600581518110610ac357610ac361211a565b6060610aa18260000151600781518110610a9457610a9461211a565b600080610f498460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b90506000610f56826114a3565b905060608085600080610f688b610ad0565b90508051600003610f835760009750505050505050506111c0565b60005b86518110156111b7578151831115610fa9576000985050505050505050506111c0565b610fcb878281518110610fbe57610fbe61211a565b60200260200101516117b7565b955085805190602001208414610fec576000985050505050505050506111c0565b611001878281518110610e6557610e6561211a565b945084516011036110d35781518303611060578c8051906020012061103286601081518110610a9457610a9461211a565b805190602001200361104f576001985050505050505050506111c0565b6000985050505050505050506111c0565b60008284815181106110745761107461211a565b016020015160f81c9050601081111561109957600099505050505050505050506111c0565b6110be868260ff16815181106110b1576110b161211a565b6020026020010151611836565b94506110cb600185612160565b9350506111a5565b845160020361104f5760006110fe6110f787600081518110610a9457610a9461211a565b8486611864565b835190915061110d8286612160565b03611160578d8051906020012061113087600181518110610a9457610a9461211a565b805190602001200361114e57600199505050505050505050506111c0565b600099505050505050505050506111c0565b8060000361117a57600099505050505050505050506111c0565b6111848185612160565b935061119c866001815181106110b1576110b161211a565b94506111a59050565b806111af81612178565b915050610f86565b50505050505050505b949350505050565b6000610aa18260000151600381518110610ac357610ac361211a565b6000610aa18260000151600481518110610ac357610ac361211a565b6000610aa18260000151600081518110610ac357610ac361211a565b6060610aa18260000151600181518110610a9457610a9461211a565b6001546040517f41539d4a000000000000000000000000000000000000000000000000000000008152600481018490526000918291829173ffffffffffffffffffffffffffffffffffffffff16906341539d4a9060240160a060405180830381865afa1580156112ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d091906121b0565b5093505092509250611327828a6112e79190612149565b6040805160208082018e90528183018d9052606082018c905260808083018c90528351808403909101815260a0909201909252805191012090858761199c565b61138d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f48454144455200000000604482015260640161052a565b505050505050505050565b60408051602081019091526060815260405180602001604052806113cc8460200151600181518110610e6557610e6561211a565b905292915050565b604080518082019091526000808252602082015282518051839081106113fc576113fc61211a565b6020026020010151905092915050565b80516000901580159061142157508151602110155b61142a57600080fd5b60006114398360200151611b49565b9050600081846000015161144d9190612149565b90506000808386602001516114629190612160565b905080519150602083101561147e57826020036101000a820491505b50949350505050565b6060610aa18260200151600281518110610a9457610a9461211a565b60606114ae826116d7565b6114b757600080fd5b60006114c283611bcb565b905060008167ffffffffffffffff8111156114df576114df611daf565b60405190808252806020026020018201604052801561152457816020015b60408051808201909152600080825260208201528152602001906001900390816114fd5790505b50905060006115368560200151611b49565b85602001516115459190612160565b90506000805b848110156115ae5761155c83611c50565b91506040518060400160405280838152602001848152508482815181106115855761158561211a565b602090810291909101015261159a8284612160565b9250806115a681612178565b91505061154b565b509195945050505050565b80516060906115c757600080fd5b60006115d68360200151611b49565b905060008184600001516115ea9190612149565b905060008167ffffffffffffffff81111561160757611607611daf565b6040519080825280601f01601f191660200182016040528015611631576020820181803683370190505b509050600081602001905061147e84876020015161164f9190612160565b8285611d12565b60006116636002846121fd565b1561169d57601082611676600286611fc4565b815181106116865761168661211a565b0160200151611698919060f81c612211565b6116cd565b6010826116ab600286611fc4565b815181106116bb576116bb61211a565b01602001516116cd919060f81c612233565b60f81b9392505050565b805160009081036116ea57506000919050565b6020820151805160001a9060c0821015611708575060009392505050565b5060019392505050565b8060000361171f57505050565b602081106117575782518252611736602084612160565b9250611743602083612160565b9150611750602082612149565b905061171f565b8060000361176457505050565b60006001611773836020612149565b61177f90610100612375565b6117899190612149565b935183518516941916939093179091525050565b80516000906015146117ae57600080fd5b610aa18261140c565b60606000826000015167ffffffffffffffff8111156117d8576117d8611daf565b6040519080825280601f01601f191660200182016040528015611802576020820181803683370190505b50905080516000036118145792915050565b600081602001905061182f8460200151828660000151611d12565b5092915050565b805160009060211461184757600080fd5b6000808360200151600161185b9190612160565b51949350505050565b6000808061187186610ad0565b90506000815167ffffffffffffffff81111561188f5761188f611daf565b6040519080825280601f01601f1916602001820160405280156118b9576020820181803683370190505b509050845b82516118ca9087612160565b81101561196d5760008782815181106118e5576118e561211a565b01602001517fff00000000000000000000000000000000000000000000000000000000000000169050808361191a8985612149565b8151811061192a5761192a61211a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050808061196590612178565b9150506118be565b50808051906020012082805190602001200361198c5781519250611991565b600092505b509095945050505050565b6000602082516119ac91906121fd565b15611a13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f496e76616c69642070726f6f66206c656e677468000000000000000000000000604482015260640161052a565b600060208351611a239190611fc4565b9050611a30816002612375565b8510611a98576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4c65616620696e64657820697320746f6f206269670000000000000000000000604482015260640161052a565b60008660205b85518111611b3b57858101519250611ab76002896121fd565b600003611aef576040805160208101849052908101849052606001604051602081830303815290604052805190602001209150611b1c565b60408051602081018590529081018390526060016040516020818303038152906040528051906020012091505b611b27600289611fc4565b9750611b34602082612160565b9050611a9e565b509094149695505050505050565b8051600090811a6080811015611b625750600092915050565b60b8811080611b7d575060c08110801590611b7d575060f881105b15611b8b5750600192915050565b60c0811015611bbf57611ba0600160b8612381565b611bad9060ff1682612149565b611bb8906001612160565b9392505050565b611ba0600160f8612381565b80516000908103611bde57506000919050565b600080611bee8460200151611b49565b8460200151611bfd9190612160565b9050600084600001518560200151611c159190612160565b90505b80821015611c4757611c2982611c50565b611c339083612160565b915082611c3f81612178565b935050611c18565b50909392505050565b80516000908190811a6080811015611c6b576001915061182f565b60b8811015611c9157611c7f608082612149565b611c8a906001612160565b915061182f565b60c0811015611cbe5760b78103600185019450806020036101000a8551046001820181019350505061182f565b60f8811015611cd257611c7f60c082612149565b60019390930151602084900360f7016101000a90049092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0a0192915050565b80600003611d1f57505050565b602081106117575782518252611d36602084612160565b9250611d43602083612160565b9150611d50602082612149565b9050611d1f565b600060208284031215611d6957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461048557600080fd5b600060208284031215611da457600080fd5b8135611bb881611d70565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611e2557611e25611daf565b604052919050565b600067ffffffffffffffff821115611e4757611e47611daf565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600060208284031215611e8557600080fd5b813567ffffffffffffffff811115611e9c57600080fd5b8201601f81018413611ead57600080fd5b8035611ec0611ebb82611e2d565b611dde565b818152856020838501011115611ed557600080fd5b81602084016020830137600091810160200191909152949350505050565b600060208284031215611f0557600080fd5b8151611bb881611d70565b600060208284031215611f2257600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611f9057611f90611f29565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611fd357611fd3611f95565b500490565b60005b83811015611ff3578181015183820152602001611fdb565b83811115612002576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260008251806040840152612043816060850160208701611fd8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b8381526000835161208e816020850160208801611fd8565b60209201918201929092526040019392505050565b6000602082840312156120b557600080fd5b815167ffffffffffffffff8111156120cc57600080fd5b8201601f810184136120dd57600080fd5b80516120eb611ebb82611e2d565b81815285602083850101111561210057600080fd5b612111826020830160208601611fd8565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008282101561215b5761215b611f29565b500390565b6000821982111561217357612173611f29565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036121a9576121a9611f29565b5060010190565b600080600080600060a086880312156121c857600080fd5b8551945060208601519350604086015192506060860151915060808601516121ef81611d70565b809150509295509295909350565b60008261220c5761220c611f95565b500690565b600060ff83168061222457612224611f95565b8060ff84160691505092915050565b600060ff83168061224657612246611f95565b8060ff84160491505092915050565b600181815b808511156122ae57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561229457612294611f29565b808516156122a157918102915b93841c939080029061225a565b509250929050565b6000826122c557506001610aa1565b816122d257506000610aa1565b81600181146122e857600281146122f25761230e565b6001915050610aa1565b60ff84111561230357612303611f29565b50506001821b610aa1565b5060208310610133831016604e8410600b8410161715612331575081810a610aa1565b61233b8383612255565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561236d5761236d611f29565b029392505050565b6000611bb883836122b6565b600060ff821660ff84168082101561239b5761239b611f29565b9003939250505056fea26469706673582212200cfd00b7fe850af701e1a0cede83add638d169eaa6768ce0a7c2ef8c2926605f64736f6c634300080f0033

Verified Source Code Full Match

Compiler: v0.8.15+commit.e14f2714 EVM: london Optimization: Yes (10000 runs)
RocketPolygonPriceMessenger.sol 53 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.13;

import "@fx-portal/tunnel/FxBaseRootTunnel.sol";

import "rocketpool/contracts/interface/network/RocketNetworkBalancesInterface.sol";
import "rocketpool/contracts/interface/RocketStorageInterface.sol";

/// @author Kane Wallmann (Rocket Pool)
/// @notice Retrieves the rETH exchange rate from Rocket Pool and submits it to the oracle contract on Polygon
contract RocketPolygonPriceMessenger is FxBaseRootTunnel {
    // Immutables
    RocketStorageInterface immutable rocketStorage;
    bytes32 immutable rocketNetworkBalancesKey;

    /// @notice The most recently submitted rate
    uint256 lastRate;

    constructor(RocketStorageInterface _rocketStorage, address _checkpointManager, address _fxRoot) FxBaseRootTunnel(_checkpointManager, _fxRoot) {
        rocketStorage = _rocketStorage;
        // Precompute storage key for RocketNetworkBalances address
        rocketNetworkBalancesKey = keccak256(abi.encodePacked("contract.address", "rocketNetworkBalances"));
    }

    /// @notice Not used
    function _processMessageFromChild(bytes memory data) internal override {
        revert();
    }

    /// @notice Returns whether the rate has changed since it was last submitted
    function rateStale() external view returns (bool) {
        return rate() != lastRate;
    }

    /// @notice Returns the calculated rETH exchange rate
    function rate() public view returns (uint256) {
        // Retrieve the inputs from RocketNetworkBalances and calculate the rate
        RocketNetworkBalancesInterface rocketNetworkBalances = RocketNetworkBalancesInterface(rocketStorage.getAddress(rocketNetworkBalancesKey));
        uint256 supply = rocketNetworkBalances.getTotalRETHSupply();
        if (supply == 0) {
            return 0;
        }
        return 1 ether * rocketNetworkBalances.getTotalETHBalance() / supply;
    }

    /// @notice Submits the current rETH exchange rate to the L2 contract
    function submitRate() external {
        lastRate = rate();
        // Send the cross chain message
        bytes memory data = abi.encodeWithSignature('updateRate(uint256)', lastRate);
        _sendMessageToChild(data);
    }
}
Merkle.sol 34 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

library Merkle {
    function checkMembership(
        bytes32 leaf,
        uint256 index,
        bytes32 rootHash,
        bytes memory proof
    ) internal pure returns (bool) {
        require(proof.length % 32 == 0, "Invalid proof length");
        uint256 proofHeight = proof.length / 32;
        // Proof of size n means, height of the tree is n+1.
        // In a tree of height n+1, max #leafs possible is 2 ^ n
        require(index < 2**proofHeight, "Leaf index is too big");

        bytes32 proofElement;
        bytes32 computedHash = leaf;
        for (uint256 i = 32; i <= proof.length; i += 32) {
            assembly {
                proofElement := mload(add(proof, i))
            }

            if (index % 2 == 0) {
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }

            index = index / 2;
        }
        return computedHash == rootHash;
    }
}
RLPReader.sol 340 lines
/*
 * @author Hamdi Allam [email protected]
 * Please reach out with any questions or concerns
 */
pragma solidity ^0.8.0;

library RLPReader {
    uint8 constant STRING_SHORT_START = 0x80;
    uint8 constant STRING_LONG_START = 0xb8;
    uint8 constant LIST_SHORT_START = 0xc0;
    uint8 constant LIST_LONG_START = 0xf8;
    uint8 constant WORD_SIZE = 32;

    struct RLPItem {
        uint256 len;
        uint256 memPtr;
    }

    struct Iterator {
        RLPItem item; // Item that's being iterated over.
        uint256 nextPtr; // Position of the next item in the list.
    }

    /*
     * @dev Returns the next element in the iteration. Reverts if it has not next element.
     * @param self The iterator.
     * @return The next element in the iteration.
     */
    function next(Iterator memory self) internal pure returns (RLPItem memory) {
        require(hasNext(self));

        uint256 ptr = self.nextPtr;
        uint256 itemLength = _itemLength(ptr);
        self.nextPtr = ptr + itemLength;

        return RLPItem(itemLength, ptr);
    }

    /*
     * @dev Returns true if the iteration has more elements.
     * @param self The iterator.
     * @return true if the iteration has more elements.
     */
    function hasNext(Iterator memory self) internal pure returns (bool) {
        RLPItem memory item = self.item;
        return self.nextPtr < item.memPtr + item.len;
    }

    /*
     * @param item RLP encoded bytes
     */
    function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) {
        uint256 memPtr;
        assembly {
            memPtr := add(item, 0x20)
        }

        return RLPItem(item.length, memPtr);
    }

    /*
     * @dev Create an iterator. Reverts if item is not a list.
     * @param self The RLP item.
     * @return An 'Iterator' over the item.
     */
    function iterator(RLPItem memory self) internal pure returns (Iterator memory) {
        require(isList(self));

        uint256 ptr = self.memPtr + _payloadOffset(self.memPtr);
        return Iterator(self, ptr);
    }

    /*
     * @param item RLP encoded bytes
     */
    function rlpLen(RLPItem memory item) internal pure returns (uint256) {
        return item.len;
    }

    /*
     * @param item RLP encoded bytes
     */
    function payloadLen(RLPItem memory item) internal pure returns (uint256) {
        return item.len - _payloadOffset(item.memPtr);
    }

    /*
     * @param item RLP encoded list in bytes
     */
    function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) {
        require(isList(item));

        uint256 items = numItems(item);
        RLPItem[] memory result = new RLPItem[](items);

        uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr);
        uint256 dataLen;
        for (uint256 i = 0; i < items; i++) {
            dataLen = _itemLength(memPtr);
            result[i] = RLPItem(dataLen, memPtr);
            memPtr = memPtr + dataLen;
        }

        return result;
    }

    // @return indicator whether encoded payload is a list. negate this function call for isData.
    function isList(RLPItem memory item) internal pure returns (bool) {
        if (item.len == 0) return false;

        uint8 byte0;
        uint256 memPtr = item.memPtr;
        assembly {
            byte0 := byte(0, mload(memPtr))
        }

        if (byte0 < LIST_SHORT_START) return false;
        return true;
    }

    /*
     * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory.
     * @return keccak256 hash of RLP encoded bytes.
     */
    function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) {
        uint256 ptr = item.memPtr;
        uint256 len = item.len;
        bytes32 result;
        assembly {
            result := keccak256(ptr, len)
        }
        return result;
    }

    function payloadLocation(RLPItem memory item) internal pure returns (uint256, uint256) {
        uint256 offset = _payloadOffset(item.memPtr);
        uint256 memPtr = item.memPtr + offset;
        uint256 len = item.len - offset; // data length
        return (memPtr, len);
    }

    /*
     * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory.
     * @return keccak256 hash of the item payload.
     */
    function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) {
        (uint256 memPtr, uint256 len) = payloadLocation(item);
        bytes32 result;
        assembly {
            result := keccak256(memPtr, len)
        }
        return result;
    }

    /** RLPItem conversions into data types **/

    // @returns raw rlp encoding in bytes
    function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) {
        bytes memory result = new bytes(item.len);
        if (result.length == 0) return result;

        uint256 ptr;
        assembly {
            ptr := add(0x20, result)
        }

        copy(item.memPtr, ptr, item.len);
        return result;
    }

    // any non-zero byte < 128 is considered true
    function toBoolean(RLPItem memory item) internal pure returns (bool) {
        require(item.len == 1);
        uint256 result;
        uint256 memPtr = item.memPtr;
        assembly {
            result := byte(0, mload(memPtr))
        }

        return result == 0 ? false : true;
    }

    function toAddress(RLPItem memory item) internal pure returns (address) {
        // 1 byte for the length prefix
        require(item.len == 21);

        return address(uint160(toUint(item)));
    }

    function toUint(RLPItem memory item) internal pure returns (uint256) {
        require(item.len > 0 && item.len <= 33);

        uint256 offset = _payloadOffset(item.memPtr);
        uint256 len = item.len - offset;

        uint256 result;
        uint256 memPtr = item.memPtr + offset;
        assembly {
            result := mload(memPtr)

            // shift to the correct location if neccesary
            if lt(len, 32) {
                result := div(result, exp(256, sub(32, len)))
            }
        }

        return result;
    }

    // enforces 32 byte length
    function toUintStrict(RLPItem memory item) internal pure returns (uint256) {
        // one byte prefix
        require(item.len == 33);

        uint256 result;
        uint256 memPtr = item.memPtr + 1;
        assembly {
            result := mload(memPtr)
        }

        return result;
    }

    function toBytes(RLPItem memory item) internal pure returns (bytes memory) {
        require(item.len > 0);

        uint256 offset = _payloadOffset(item.memPtr);
        uint256 len = item.len - offset; // data length
        bytes memory result = new bytes(len);

        uint256 destPtr;
        assembly {
            destPtr := add(0x20, result)
        }

        copy(item.memPtr + offset, destPtr, len);
        return result;
    }

    /*
     * Private Helpers
     */

    // @return number of payload items inside an encoded list.
    function numItems(RLPItem memory item) private pure returns (uint256) {
        if (item.len == 0) return 0;

        uint256 count = 0;
        uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr);
        uint256 endPtr = item.memPtr + item.len;
        while (currPtr < endPtr) {
            currPtr = currPtr + _itemLength(currPtr); // skip over an item
            count++;
        }

        return count;
    }

    // @return entire rlp item byte length
    function _itemLength(uint256 memPtr) private pure returns (uint256) {
        uint256 itemLen;
        uint256 byte0;
        assembly {
            byte0 := byte(0, mload(memPtr))
        }

        if (byte0 < STRING_SHORT_START) itemLen = 1;
        else if (byte0 < STRING_LONG_START) itemLen = byte0 - STRING_SHORT_START + 1;
        else if (byte0 < LIST_SHORT_START) {
            assembly {
                let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is
                memPtr := add(memPtr, 1) // skip over the first byte
                /* 32 byte word size */
                let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len
                itemLen := add(dataLen, add(byteLen, 1))
            }
        } else if (byte0 < LIST_LONG_START) {
            itemLen = byte0 - LIST_SHORT_START + 1;
        } else {
            assembly {
                let byteLen := sub(byte0, 0xf7)
                memPtr := add(memPtr, 1)

                let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length
                itemLen := add(dataLen, add(byteLen, 1))
            }
        }

        return itemLen;
    }

    // @return number of bytes until the data
    function _payloadOffset(uint256 memPtr) private pure returns (uint256) {
        uint256 byte0;
        assembly {
            byte0 := byte(0, mload(memPtr))
        }

        if (byte0 < STRING_SHORT_START) return 0;
        else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) return 1;
        else if (byte0 < LIST_SHORT_START)
            // being explicit
            return byte0 - (STRING_LONG_START - 1) + 1;
        else return byte0 - (LIST_LONG_START - 1) + 1;
    }

    /*
     * @param src Pointer to source
     * @param dest Pointer to destination
     * @param len Amount of memory to copy from the source
     */
    function copy(
        uint256 src,
        uint256 dest,
        uint256 len
    ) private pure {
        if (len == 0) return;

        // copy as many word sizes as possible
        for (; len >= WORD_SIZE; len -= WORD_SIZE) {
            assembly {
                mstore(dest, mload(src))
            }

            src += WORD_SIZE;
            dest += WORD_SIZE;
        }

        if (len == 0) return;

        // left over bytes. Mask is used to remove unwanted bytes from the word
        uint256 mask = 256**(WORD_SIZE - len) - 1;

        assembly {
            let srcpart := and(mload(src), not(mask)) // zero out src
            let destpart := and(mload(dest), mask) // retrieve the bytes
            mstore(dest, or(destpart, srcpart))
        }
    }
}
ExitPayloadReader.sol 162 lines
pragma solidity ^0.8.0;

import {RLPReader} from "./RLPReader.sol";

library ExitPayloadReader {
    using RLPReader for bytes;
    using RLPReader for RLPReader.RLPItem;

    uint8 constant WORD_SIZE = 32;

    struct ExitPayload {
        RLPReader.RLPItem[] data;
    }

    struct Receipt {
        RLPReader.RLPItem[] data;
        bytes raw;
        uint256 logIndex;
    }

    struct Log {
        RLPReader.RLPItem data;
        RLPReader.RLPItem[] list;
    }

    struct LogTopics {
        RLPReader.RLPItem[] data;
    }

    // copy paste of private copy() from RLPReader to avoid changing of existing contracts
    function copy(
        uint256 src,
        uint256 dest,
        uint256 len
    ) private pure {
        if (len == 0) return;

        // copy as many word sizes as possible
        for (; len >= WORD_SIZE; len -= WORD_SIZE) {
            assembly {
                mstore(dest, mload(src))
            }

            src += WORD_SIZE;
            dest += WORD_SIZE;
        }

        if (len == 0) return;

        // left over bytes. Mask is used to remove unwanted bytes from the word
        uint256 mask = 256**(WORD_SIZE - len) - 1;
        assembly {
            let srcpart := and(mload(src), not(mask)) // zero out src
            let destpart := and(mload(dest), mask) // retrieve the bytes
            mstore(dest, or(destpart, srcpart))
        }
    }

    function toExitPayload(bytes memory data) internal pure returns (ExitPayload memory) {
        RLPReader.RLPItem[] memory payloadData = data.toRlpItem().toList();

        return ExitPayload(payloadData);
    }

    function getHeaderNumber(ExitPayload memory payload) internal pure returns (uint256) {
        return payload.data[0].toUint();
    }

    function getBlockProof(ExitPayload memory payload) internal pure returns (bytes memory) {
        return payload.data[1].toBytes();
    }

    function getBlockNumber(ExitPayload memory payload) internal pure returns (uint256) {
        return payload.data[2].toUint();
    }

    function getBlockTime(ExitPayload memory payload) internal pure returns (uint256) {
        return payload.data[3].toUint();
    }

    function getTxRoot(ExitPayload memory payload) internal pure returns (bytes32) {
        return bytes32(payload.data[4].toUint());
    }

    function getReceiptRoot(ExitPayload memory payload) internal pure returns (bytes32) {
        return bytes32(payload.data[5].toUint());
    }

    function getReceipt(ExitPayload memory payload) internal pure returns (Receipt memory receipt) {
        receipt.raw = payload.data[6].toBytes();
        RLPReader.RLPItem memory receiptItem = receipt.raw.toRlpItem();

        if (receiptItem.isList()) {
            // legacy tx
            receipt.data = receiptItem.toList();
        } else {
            // pop first byte before parsing receipt
            bytes memory typedBytes = receipt.raw;
            bytes memory result = new bytes(typedBytes.length - 1);
            uint256 srcPtr;
            uint256 destPtr;
            assembly {
                srcPtr := add(33, typedBytes)
                destPtr := add(0x20, result)
            }

            copy(srcPtr, destPtr, result.length);
            receipt.data = result.toRlpItem().toList();
        }

        receipt.logIndex = getReceiptLogIndex(payload);
        return receipt;
    }

    function getReceiptProof(ExitPayload memory payload) internal pure returns (bytes memory) {
        return payload.data[7].toBytes();
    }

    function getBranchMaskAsBytes(ExitPayload memory payload) internal pure returns (bytes memory) {
        return payload.data[8].toBytes();
    }

    function getBranchMaskAsUint(ExitPayload memory payload) internal pure returns (uint256) {
        return payload.data[8].toUint();
    }

    function getReceiptLogIndex(ExitPayload memory payload) internal pure returns (uint256) {
        return payload.data[9].toUint();
    }

    // Receipt methods
    function toBytes(Receipt memory receipt) internal pure returns (bytes memory) {
        return receipt.raw;
    }

    function getLog(Receipt memory receipt) internal pure returns (Log memory) {
        RLPReader.RLPItem memory logData = receipt.data[3].toList()[receipt.logIndex];
        return Log(logData, logData.toList());
    }

    // Log methods
    function getEmitter(Log memory log) internal pure returns (address) {
        return RLPReader.toAddress(log.list[0]);
    }

    function getTopics(Log memory log) internal pure returns (LogTopics memory) {
        return LogTopics(log.list[1].toList());
    }

    function getData(Log memory log) internal pure returns (bytes memory) {
        return log.list[2].toBytes();
    }

    function toRlpBytes(Log memory log) internal pure returns (bytes memory) {
        return log.data.toRlpBytes();
    }

    // LogTopics methods
    function getField(LogTopics memory topics, uint256 index) internal pure returns (RLPReader.RLPItem memory) {
        return topics.data[index];
    }
}
MerklePatriciaProof.sol 137 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {RLPReader} from "./RLPReader.sol";

library MerklePatriciaProof {
    /*
     * @dev Verifies a merkle patricia proof.
     * @param value The terminating value in the trie.
     * @param encodedPath The path in the trie leading to value.
     * @param rlpParentNodes The rlp encoded stack of nodes.
     * @param root The root hash of the trie.
     * @return The boolean validity of the proof.
     */
    function verify(
        bytes memory value,
        bytes memory encodedPath,
        bytes memory rlpParentNodes,
        bytes32 root
    ) internal pure returns (bool) {
        RLPReader.RLPItem memory item = RLPReader.toRlpItem(rlpParentNodes);
        RLPReader.RLPItem[] memory parentNodes = RLPReader.toList(item);

        bytes memory currentNode;
        RLPReader.RLPItem[] memory currentNodeList;

        bytes32 nodeKey = root;
        uint256 pathPtr = 0;

        bytes memory path = _getNibbleArray(encodedPath);
        if (path.length == 0) {
            return false;
        }

        for (uint256 i = 0; i < parentNodes.length; i++) {
            if (pathPtr > path.length) {
                return false;
            }

            currentNode = RLPReader.toRlpBytes(parentNodes[i]);
            if (nodeKey != keccak256(currentNode)) {
                return false;
            }
            currentNodeList = RLPReader.toList(parentNodes[i]);

            if (currentNodeList.length == 17) {
                if (pathPtr == path.length) {
                    if (keccak256(RLPReader.toBytes(currentNodeList[16])) == keccak256(value)) {
                        return true;
                    } else {
                        return false;
                    }
                }

                uint8 nextPathNibble = uint8(path[pathPtr]);
                if (nextPathNibble > 16) {
                    return false;
                }
                nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[nextPathNibble]));
                pathPtr += 1;
            } else if (currentNodeList.length == 2) {
                uint256 traversed = _nibblesToTraverse(RLPReader.toBytes(currentNodeList[0]), path, pathPtr);
                if (pathPtr + traversed == path.length) {
                    //leaf node
                    if (keccak256(RLPReader.toBytes(currentNodeList[1])) == keccak256(value)) {
                        return true;
                    } else {
                        return false;
                    }
                }

                //extension node
                if (traversed == 0) {
                    return false;
                }

                pathPtr += traversed;
                nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[1]));
            } else {
                return false;
            }
        }
    }

    function _nibblesToTraverse(
        bytes memory encodedPartialPath,
        bytes memory path,
        uint256 pathPtr
    ) private pure returns (uint256) {
        uint256 len = 0;
        // encodedPartialPath has elements that are each two hex characters (1 byte), but partialPath
        // and slicedPath have elements that are each one hex character (1 nibble)
        bytes memory partialPath = _getNibbleArray(encodedPartialPath);
        bytes memory slicedPath = new bytes(partialPath.length);

        // pathPtr counts nibbles in path
        // partialPath.length is a number of nibbles
        for (uint256 i = pathPtr; i < pathPtr + partialPath.length; i++) {
            bytes1 pathNibble = path[i];
            slicedPath[i - pathPtr] = pathNibble;
        }

        if (keccak256(partialPath) == keccak256(slicedPath)) {
            len = partialPath.length;
        } else {
            len = 0;
        }
        return len;
    }

    // bytes b must be hp encoded
    function _getNibbleArray(bytes memory b) internal pure returns (bytes memory) {
        bytes memory nibbles = "";
        if (b.length > 0) {
            uint8 offset;
            uint8 hpNibble = uint8(_getNthNibbleOfBytes(0, b));
            if (hpNibble == 1 || hpNibble == 3) {
                nibbles = new bytes(b.length * 2 - 1);
                bytes1 oddNibble = _getNthNibbleOfBytes(1, b);
                nibbles[0] = oddNibble;
                offset = 1;
            } else {
                nibbles = new bytes(b.length * 2 - 2);
                offset = 0;
            }

            for (uint256 i = offset; i < nibbles.length; i++) {
                nibbles[i] = _getNthNibbleOfBytes(i - offset + 2, b);
            }
        }
        return nibbles;
    }

    function _getNthNibbleOfBytes(uint256 n, bytes memory str) private pure returns (bytes1) {
        return bytes1(n % 2 == 0 ? uint8(str[n / 2]) / 0x10 : uint8(str[n / 2]) % 0x10);
    }
}
FxBaseRootTunnel.sol 178 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {RLPReader} from "../lib/RLPReader.sol";
import {MerklePatriciaProof} from "../lib/MerklePatriciaProof.sol";
import {Merkle} from "../lib/Merkle.sol";
import "../lib/ExitPayloadReader.sol";

interface IFxStateSender {
    function sendMessageToChild(address _receiver, bytes calldata _data) external;
}

contract ICheckpointManager {
    struct HeaderBlock {
        bytes32 root;
        uint256 start;
        uint256 end;
        uint256 createdAt;
        address proposer;
    }

    /**
     * @notice mapping of checkpoint header numbers to block details
     * @dev These checkpoints are submited by plasma contracts
     */
    mapping(uint256 => HeaderBlock) public headerBlocks;
}

abstract contract FxBaseRootTunnel {
    using RLPReader for RLPReader.RLPItem;
    using Merkle for bytes32;
    using ExitPayloadReader for bytes;
    using ExitPayloadReader for ExitPayloadReader.ExitPayload;
    using ExitPayloadReader for ExitPayloadReader.Log;
    using ExitPayloadReader for ExitPayloadReader.LogTopics;
    using ExitPayloadReader for ExitPayloadReader.Receipt;

    // keccak256(MessageSent(bytes))
    bytes32 public constant SEND_MESSAGE_EVENT_SIG = 0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036;

    // state sender contract
    IFxStateSender public fxRoot;
    // root chain manager
    ICheckpointManager public checkpointManager;
    // child tunnel contract which receives and sends messages
    address public fxChildTunnel;

    // storage to avoid duplicate exits
    mapping(bytes32 => bool) public processedExits;

    constructor(address _checkpointManager, address _fxRoot) {
        checkpointManager = ICheckpointManager(_checkpointManager);
        fxRoot = IFxStateSender(_fxRoot);
    }

    // set fxChildTunnel if not set already
    function setFxChildTunnel(address _fxChildTunnel) public virtual {
        require(fxChildTunnel == address(0x0), "FxBaseRootTunnel: CHILD_TUNNEL_ALREADY_SET");
        fxChildTunnel = _fxChildTunnel;
    }

    /**
     * @notice Send bytes message to Child Tunnel
     * @param message bytes message that will be sent to Child Tunnel
     * some message examples -
     *   abi.encode(tokenId);
     *   abi.encode(tokenId, tokenMetadata);
     *   abi.encode(messageType, messageData);
     */
    function _sendMessageToChild(bytes memory message) internal {
        fxRoot.sendMessageToChild(fxChildTunnel, message);
    }

    function _validateAndExtractMessage(bytes memory inputData) internal returns (bytes memory) {
        ExitPayloadReader.ExitPayload memory payload = inputData.toExitPayload();

        bytes memory branchMaskBytes = payload.getBranchMaskAsBytes();
        uint256 blockNumber = payload.getBlockNumber();
        // checking if exit has already been processed
        // unique exit is identified using hash of (blockNumber, branchMask, receiptLogIndex)
        bytes32 exitHash = keccak256(
            abi.encodePacked(
                blockNumber,
                // first 2 nibbles are dropped while generating nibble array
                // this allows branch masks that are valid but bypass exitHash check (changing first 2 nibbles only)
                // so converting to nibble array and then hashing it
                MerklePatriciaProof._getNibbleArray(branchMaskBytes),
                payload.getReceiptLogIndex()
            )
        );
        require(processedExits[exitHash] == false, "FxRootTunnel: EXIT_ALREADY_PROCESSED");
        processedExits[exitHash] = true;

        ExitPayloadReader.Receipt memory receipt = payload.getReceipt();
        ExitPayloadReader.Log memory log = receipt.getLog();

        // check child tunnel
        require(fxChildTunnel == log.getEmitter(), "FxRootTunnel: INVALID_FX_CHILD_TUNNEL");

        bytes32 receiptRoot = payload.getReceiptRoot();
        // verify receipt inclusion
        require(
            MerklePatriciaProof.verify(receipt.toBytes(), branchMaskBytes, payload.getReceiptProof(), receiptRoot),
            "FxRootTunnel: INVALID_RECEIPT_PROOF"
        );

        // verify checkpoint inclusion
        _checkBlockMembershipInCheckpoint(
            blockNumber,
            payload.getBlockTime(),
            payload.getTxRoot(),
            receiptRoot,
            payload.getHeaderNumber(),
            payload.getBlockProof()
        );

        ExitPayloadReader.LogTopics memory topics = log.getTopics();

        require(
            bytes32(topics.getField(0).toUint()) == SEND_MESSAGE_EVENT_SIG, // topic0 is event sig
            "FxRootTunnel: INVALID_SIGNATURE"
        );

        // received message data
        bytes memory message = abi.decode(log.getData(), (bytes)); // event decodes params again, so decoding bytes to get message
        return message;
    }

    function _checkBlockMembershipInCheckpoint(
        uint256 blockNumber,
        uint256 blockTime,
        bytes32 txRoot,
        bytes32 receiptRoot,
        uint256 headerNumber,
        bytes memory blockProof
    ) private view {
        (bytes32 headerRoot, uint256 startBlock, , uint256 createdAt, ) = checkpointManager.headerBlocks(headerNumber);

        require(
            keccak256(abi.encodePacked(blockNumber, blockTime, txRoot, receiptRoot)).checkMembership(
                blockNumber - startBlock,
                headerRoot,
                blockProof
            ),
            "FxRootTunnel: INVALID_HEADER"
        );
    }

    /**
     * @notice receive message from  L2 to L1, validated by proof
     * @dev This function verifies if the transaction actually happened on child chain
     *
     * @param inputData RLP encoded data of the reference tx containing following list of fields
     *  0 - headerNumber - Checkpoint header block number containing the reference tx
     *  1 - blockProof - Proof that the block header (in the child chain) is a leaf in the submitted merkle root
     *  2 - blockNumber - Block number containing the reference tx on child chain
     *  3 - blockTime - Reference tx block time
     *  4 - txRoot - Transactions root of block
     *  5 - receiptRoot - Receipts root of block
     *  6 - receipt - Receipt of the reference transaction
     *  7 - receiptProof - Merkle proof of the reference receipt
     *  8 - branchMask - 32 bits denoting the path of receipt in merkle tree
     *  9 - receiptLogIndex - Log Index to read from the receipt
     */
    function receiveMessage(bytes memory inputData) public virtual {
        bytes memory message = _validateAndExtractMessage(inputData);
        _processMessageFromChild(message);
    }

    /**
     * @notice Process message received from Child Tunnel
     * @dev function needs to be implemented to handle message as per requirement
     * This is called by receiveMessage function.
     * Since it is called via a system call, any event will not be emitted during its execution.
     * @param message bytes message that was sent from Child Tunnel
     */
    function _processMessageFromChild(bytes memory message) internal virtual;
}
RocketStorageInterface.sol 51 lines
pragma solidity >0.5.0 <0.9.0;

// SPDX-License-Identifier: GPL-3.0-only

interface RocketStorageInterface {

    // Deploy status
    function getDeployedStatus() external view returns (bool);

    // Guardian
    function getGuardian() external view returns(address);
    function setGuardian(address _newAddress) external;
    function confirmGuardian() external;

    // Getters
    function getAddress(bytes32 _key) external view returns (address);
    function getUint(bytes32 _key) external view returns (uint);
    function getString(bytes32 _key) external view returns (string memory);
    function getBytes(bytes32 _key) external view returns (bytes memory);
    function getBool(bytes32 _key) external view returns (bool);
    function getInt(bytes32 _key) external view returns (int);
    function getBytes32(bytes32 _key) external view returns (bytes32);

    // Setters
    function setAddress(bytes32 _key, address _value) external;
    function setUint(bytes32 _key, uint _value) external;
    function setString(bytes32 _key, string calldata _value) external;
    function setBytes(bytes32 _key, bytes calldata _value) external;
    function setBool(bytes32 _key, bool _value) external;
    function setInt(bytes32 _key, int _value) external;
    function setBytes32(bytes32 _key, bytes32 _value) external;

    // Deleters
    function deleteAddress(bytes32 _key) external;
    function deleteUint(bytes32 _key) external;
    function deleteString(bytes32 _key) external;
    function deleteBytes(bytes32 _key) external;
    function deleteBool(bytes32 _key) external;
    function deleteInt(bytes32 _key) external;
    function deleteBytes32(bytes32 _key) external;

    // Arithmetic
    function addUint(bytes32 _key, uint256 _amount) external;
    function subUint(bytes32 _key, uint256 _amount) external;

    // Protected storage
    function getNodeWithdrawalAddress(address _nodeAddress) external view returns (address);
    function getNodePendingWithdrawalAddress(address _nodeAddress) external view returns (address);
    function setWithdrawalAddress(address _nodeAddress, address _newWithdrawalAddress, bool _confirm) external;
    function confirmWithdrawalAddress(address _nodeAddress) external;
}
RocketNetworkBalancesInterface.sol 14 lines
pragma solidity >0.5.0 <0.9.0;

// SPDX-License-Identifier: GPL-3.0-only

interface RocketNetworkBalancesInterface {
    function getBalancesBlock() external view returns (uint256);
    function getLatestReportableBlock() external view returns (uint256);
    function getTotalETHBalance() external view returns (uint256);
    function getStakingETHBalance() external view returns (uint256);
    function getTotalRETHSupply() external view returns (uint256);
    function getETHUtilizationRate() external view returns (uint256);
    function submitBalances(uint256 _block, uint256 _total, uint256 _staking, uint256 _rethSupply) external;
    function executeUpdateBalances(uint256 _block, uint256 _totalEth, uint256 _stakingEth, uint256 _rethSupply) external;
}

Read Contract

SEND_MESSAGE_EVENT_SIG 0x0e387de6 → bytes32
checkpointManager 0xc0857ba0 → address
fxChildTunnel 0x972c4928 → address
fxRoot 0xde9b771f → address
processedExits 0x607f2d42 → bool
rate 0x2c4e722e → uint256
rateStale 0xee0eb4a1 → bool

Write Contract 3 functions

These functions modify contract state and require a wallet transaction to execute.

receiveMessage 0xf953cec7
bytes inputData
setFxChildTunnel 0xaea4e49e
address _fxChildTunnel
submitRate 0x9c14b3a8
No parameters

Recent Transactions

No transactions found for this address